如何使用 Nokogiri 获得第一级 children for XML
How to get first level children for XML using Nokogiri
我正在尝试使用 Nokogiri 解析 POM 文件,并希望获得第一级 child 个节点。
我的 POM 文件看起来像这样:
<project xmlns="some.maven.link">
<parent>
<groupId>parent.jar</groupId>
<artifactId>parent-jar</artifactId>
</parent>
<groupId>child.jar</groupId>
<artifactId>child-jar</artifactId>
</project>
我正在尝试获取 artifactId "child-jar",但我使用的 XPath 可能不正确,它在第一次出现时获取我 "parent.jar"。
这是我的 Ruby 代码:
@pom = Nokogiri::XML(File.open(file_path))
p @pom.xpath("/project/artifactId", project"=>"http://maven.apache.org/POM/4.0.0")[0].text
我可以访问第二个元素,但这只是一个 hack。
您的 XML 示例似乎不正确。简化它:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<project>
<parent>
<groupId>parent.jar</groupId>
<artifactId>parent-jar</artifactId>
</parent>
<groupId>child.jar</groupId>
<artifactId>child-jar</artifactId>
</project>
EOT
doc.at('project > artifactId').text # => "child-jar"
我会使用 XPath:
doc.at('/project/artifactId').text # => "child-jar"
我建议学习 search
、xpath
、css
和它们的 at*
表兄弟之间的区别,这些都记录在“Searching a XML/HTML Document" and Node文档。
在上面的示例中,我删除了 XML 名称空间信息以简化操作。 XML 命名空间很有用,但也很烦人,在您的示例中 XML 您没有提供有效的 URL 就破坏了它。修复示例:
<project xmlns="http://www.w3.org/1999/xhtml">
我可以使用:
namespaces = doc.collect_namespaces # => {"xmlns"=>"http://www.w3.org/1999/xhtml"}
doc.at('project > artifactId', namespaces).text # => "child-jar"
或:
doc.at('xmlns|project > xmlns|artifactId').text # => "child-jar"
我更喜欢并推荐第一个,因为它更具可读性且噪音较小。
Nokogiri 在选择器中实现 CSS 有助于简化大多数选择器。在文档中传递收集的名称空间可以简化搜索,无论您使用的是 CSS 还是 XPath。
这些也有效:
doc.at('/xmlns:project/xmlns:artifactId').text # => "child-jar"
doc.at('/foo:project/foo:artifactId', {'foo' => "http://www.w3.org/1999/xhtml"}).text # => "child-jar"
请注意,第二个使用重命名的命名空间,如果您正在处理文档中的冗余 xmlns
声明并且需要区分它们,这将很有用。
Nokogiri 的“Namespaces”教程很有帮助。
我正在尝试使用 Nokogiri 解析 POM 文件,并希望获得第一级 child 个节点。
我的 POM 文件看起来像这样:
<project xmlns="some.maven.link">
<parent>
<groupId>parent.jar</groupId>
<artifactId>parent-jar</artifactId>
</parent>
<groupId>child.jar</groupId>
<artifactId>child-jar</artifactId>
</project>
我正在尝试获取 artifactId "child-jar",但我使用的 XPath 可能不正确,它在第一次出现时获取我 "parent.jar"。
这是我的 Ruby 代码:
@pom = Nokogiri::XML(File.open(file_path))
p @pom.xpath("/project/artifactId", project"=>"http://maven.apache.org/POM/4.0.0")[0].text
我可以访问第二个元素,但这只是一个 hack。
您的 XML 示例似乎不正确。简化它:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<project>
<parent>
<groupId>parent.jar</groupId>
<artifactId>parent-jar</artifactId>
</parent>
<groupId>child.jar</groupId>
<artifactId>child-jar</artifactId>
</project>
EOT
doc.at('project > artifactId').text # => "child-jar"
我会使用 XPath:
doc.at('/project/artifactId').text # => "child-jar"
我建议学习 search
、xpath
、css
和它们的 at*
表兄弟之间的区别,这些都记录在“Searching a XML/HTML Document" and Node文档。
在上面的示例中,我删除了 XML 名称空间信息以简化操作。 XML 命名空间很有用,但也很烦人,在您的示例中 XML 您没有提供有效的 URL 就破坏了它。修复示例:
<project xmlns="http://www.w3.org/1999/xhtml">
我可以使用:
namespaces = doc.collect_namespaces # => {"xmlns"=>"http://www.w3.org/1999/xhtml"}
doc.at('project > artifactId', namespaces).text # => "child-jar"
或:
doc.at('xmlns|project > xmlns|artifactId').text # => "child-jar"
我更喜欢并推荐第一个,因为它更具可读性且噪音较小。 Nokogiri 在选择器中实现 CSS 有助于简化大多数选择器。在文档中传递收集的名称空间可以简化搜索,无论您使用的是 CSS 还是 XPath。
这些也有效:
doc.at('/xmlns:project/xmlns:artifactId').text # => "child-jar"
doc.at('/foo:project/foo:artifactId', {'foo' => "http://www.w3.org/1999/xhtml"}).text # => "child-jar"
请注意,第二个使用重命名的命名空间,如果您正在处理文档中的冗余 xmlns
声明并且需要区分它们,这将很有用。
Nokogiri 的“Namespaces”教程很有帮助。