Perl XML :: LibXML:findnode vs. findvalue vs. find - 有什么区别?

Cra*_*igP 13 perl xpath libxml2

我正在使用XML::LibXML,我只需要计算XPath表达式指定的节点数.

使用下面前两个代码行中的任何一个产生我正在寻找的东西.我可以使用或不使用countXPath函数(是的,我知道,因为它返回一个列表).findvaluefindfindnodes

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!
Run Code Online (Sandbox Code Playgroud)

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

$string = $node->findvalue($xpath)
$result = $node->find($xpath)
@nodes  = $node->findnodes($xpath_expression)
Run Code Online (Sandbox Code Playgroud)
  1. 论证$xpath_expression$xpath文档之间是否真的存在差异?

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

我试图理解使用一种查找类型的重要性 - 谢谢!

Bor*_*din 18

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

  • findnodes用于返回节点列表.如果在列表上下文中调用该方法,则它返回相应类型的对象列表,例如XML::LibXML::Element,XML::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!
Run Code Online (Sandbox Code Playgroud)

这设置$node_cnt为一个简单的Perl号,而这个

my $node_cnt = $dom->find("count($xpath_str)");  # WORKS!
Run Code Online (Sandbox Code Playgroud)

设置$node_cnt为一个XML::LibXML::Number对象,碰巧stringify(当你打印它时)与前一个语句相同.print ref $node_cnt在两种情况下通过打印证明这一点.

然后

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

失败,因为XPath count求值为数字,而不是XML节点(它不是XML树的一部分).无法将数字转换为节点,因此结果为空列表.如果它是反过来的,并且我们调用findvalue了一个表达式来评估节点列表,那么有一种模糊的方法可以转换为文本值并findvalue尽力而为,并返回包含的所有文本节点的串联.列表中的节点.