获取标签名称的xpath语法是什么?

12

我正在使用 Nokogiri 解析一个大型XML文件。假设我有以下结构:

<menagerie>
  <penguin>Pablo</penguin>
  <penguin>Mortimer</penguin>
  <bull>Ferdinand</bull>
  <aardvark>James Cornelius Madison Humphrey Zophar Handlebrush III</aardvark>
</menagerie>

我可以像这样数出非企鹅:

xml.xpath('//menagerie//*[not(penguin)]').length // 2

但我如何获取标签列表,就像这样?(确切的格式并不重要;我只是想直观地浏览非企鹅标签。)

bull
aardvark

更新

这样做给了我想要的列表 - 感谢 OdedTMNdelnan

xml.xpath('//menageries/*[not(penguin)]').each do |node|
  puts node.name()
end

“xpath”调用会返回匹配的元素(我猜是某种集合)。为什么不能获取每个项目的“.tagname”(或类似的)属性? - user395760
1
不是 grep,而是在 Ruby 中收集每个项目的标签名称。类似于 tags = xml.xpath(...).collect { |tag| tag.tagname} - user395760
在 Ruby 1.9 中,您可以使用 xml.xpath(...).map(&:name) 来缩短代码。 - Phrogz
@Phrogz - 这并不常见,但它确实可以给你一个更清晰的调试信息,因为解释器现在知道你正在尝试使用一个方法而不是一个变量。 - Nathan Long
@NathanLong 顺便说一下,如果你有 foo.bar 那么 bar 总是一个方法调用。但你说得很对,仅使用 bar() 对于解释器在出错时的歧义较少。 - Phrogz
显示剩余2条评论
2个回答

13

我一定做错了什么。xml.xpath('//meagerie/*[not(penguin)]').name() 给我返回一个未定义的方法错误;同样的问题也出现在 .local-name 上。我还尝试过加上括号:name()local-name()。但是它会报错:NoMethodError: undefined method name' for #Nokogiri::XML::NodeSet:0x122f06c48`。 - Nathan Long
是的,但我不理解它们。name() 应该放在 xpath 内吗?我也尝试了那样做,但得到了无效语法错误。这似乎不是 Nokogiri 的方法。 - Nathan Long
@Nathan Long - 我认为这些应该可以直接使用:xml.xpath('name()')xml.xpath('local-name()') - Oded
1
看起来你得到了一个 NodeSet,你需要迭代它并在每个元素上调用 .name() - TMN
看起来你正在使用XPath 1.0。在XPath 2.0中,一个表达式可以返回一系列字符串:因此distinct-values(//*/local-name())将返回不同的元素名称。不幸的是,XPath 1.0只能返回一组节点,但只有一个单独的字符串;因此,您必须在XPath中检索节点,并使用主机语言编码获取它们的名称。 - Michael Kay

4

我知道这有点过时了,但你应该这样做:xml.xpath('//meagerie / *[not(企鹅)] / name()')作为表达式。请注意斜杠而不是点。这是在XPath中调用当前节点上的方法的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接