【问题标题】:Perl XML::LibXML: findnode vs. findvalue vs. find - what's the difference?Perl XML::LibXML: findnode vs. findvalue vs. find - 有什么区别?
【发布时间】:2023-03-24 18:21:02
【问题描述】:

我正在使用XML::LibXML,我只需要获取由 XPath 表达式指定的节点数。

使用下面的前两个代码行中的任何一个都会产生我正在寻找的内容。我可以将count XPath 函数与findvaluefind 一起使用,但不能与findnodes 一起使用(是的,我知道,因为它返回一个列表)。

my $node_cnt = $dom->findvalue("count($xpath_str)");  # WORKS!
my $node_cnt = $dom->find("count($xpath_str)");       # WORKS!
my @node_cnt = $dom->findnodes("count($xpath_str)");  # count doesn't work!

这导致我提出一个普遍的唠叨问题: 三种find 类型有什么区别?在文档中,它说:

$string = $node->findvalue($xpath)
$result = $node->find($xpath)
@nodes  = $node->findnodes($xpath_expression)
  1. 文档中的参数$xpath_expression$xpath 之间真的有区别吗?

  2. 对于返回标量的两个,有什么区别?

我试图了解使用一种查找类型而不是另一种查找类型的重要性 - 谢谢!

【问题讨论】:

    标签: perl xpath libxml2


    【解决方案1】:

    区别在于方法返回的值的类型。

    • findnodes 用于返回节点列表。如果在列表上下文中调用该方法,则返回适当类型的对象列表,例如XML::LibXML::ElementXML::LibXML::Text 等。如果在标量上下文中调用该方法,则返回单个 XML::LibXML::NodeList 对象,其中包含相同的信息。

      不能用于返回任意表达式,例如$dom->findnodes('42') 将不返回任何内容。您只能从此方法获取列表文档节点。

    • findvalue 用于返回单个文本或数字,即不是 XML 节点。如果您传递一个计算结果为节点列表的 XPath 表达式,那么它将通过连接列表中任何节点中的所有文本节点将该列表转换为文本。

    • find 可以返回任何内容。它将以XML::LibXML::NodeList 对象的形式返回一个节点列表,以XML::LibXML::Number 对象的形式返回一个数值,以XML::LibXML::Literal 对象的形式返回一个字符串字面量等。与findnodes 不同,它总是 返回一个单个标量值,即使在列表上下文中调用。

      我从未选择使用find。当您不知道会得到什么样的结果时,它似乎是为了包罗万象。

    例如,您可能希望编写my $nrecs = $dom->findvalue('count(/root/record)') 来获取根元素中的记录数。 $nrecs 将是一个简单的 perl 数值。

    另一方面,要获得这些记录的列表,您可以使用my @records = $dom->findnodes('/root/record')。现在@records 包含许多XML::LibXML::Element 对象。

    在你的例子中,

    my $node_cnt = $dom->findvalue("count($xpath_str)");  # WORKS!
    

    这会将$node_cnt 设置为一个简单的 Perl 数字,而这

    my $node_cnt = $dom->find("count($xpath_str)");  # WORKS!
    

    $node_cnt 设置为XML::LibXML::Number 对象,这恰好将字符串化(当您打印它时)与前面的语句相同。通过在这两种情况下打印 print ref $node_cnt 来证明这一点。

    然后

    my @node_cnt = $dom->findnodes("count($xpath_str)");  # count doesn't work!
    

    失败,因为 XPath count 计算结果为数字,而不是 XML 节点(它不是 XML 树的一部分)。无法将数字转换为节点,因此结果是一个空列表。如果反过来,我们在一个计算为节点列表的表达式上调用了findvalue,那么有一种转换为文本值的模糊合理的方法,findvalue 尽其所能并返回连接列表中的节点所包含的所有文本节点。

    【讨论】:

    • 谢谢您,谢谢您……这对您有很大帮助!!!!我也将远离“find”并相应地使用“findvalue”或“findnodes”。
    猜你喜欢
    • 1970-01-01
    • 2011-05-23
    • 2012-05-21
    • 2022-08-17
    • 2014-07-01
    • 2021-07-16
    • 2013-03-18
    • 1970-01-01
    相关资源
    最近更新 更多