如何搜索具有在同一节点中定义的命名空间的节点

时间:2012-12-17 08:19:06

标签: ruby nokogiri

如果祖先节点定义了名称空间,我可以使用它们:

> Nokogiri::XML(<<-XML
<?xml version='1.0' encoding='UTF-8'?>
<package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid">
  <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
    <dc:creator opf:role="aut">John Doe</dc:creator>
  </metadata>
</package>
XML
> xml.at_xpath("//dc:creator[@opf:role='aut']", xml.at_xpath("//xmlns:metadata").namespaces).text
 => "John Doe" 

但是,如何处理XML?

> Nokogiri::XML(<<-XML
<?xml version='1.0' encoding='UTF-8'?>
<package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid">
  <metadata>
    <dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf" opf:role="aut">John Doe</dc:creator>
  </metadata>
</package>
XML
> xml.at_xpath("//dc:creator[@opf:role='aut']", xml.at_xpath("//xmlns:metadata").namespaces).text
Nokogiri::XML::XPath::SyntaxError: Undefined namespace prefix: //dc:creator[@opf:role='aut']

我认为xml.remove_namespaces!at_xpath的文字命名空间参数是最后的手段。

1 个答案:

答案 0 :(得分:6)

要以编程方式收集所有命名空间,请使用Document#collect_namespaces

xml = Nokogiri::XML(xmldata)

ns = xml.collect_namespaces

puts xml.at('//dc:creator[@opf:role="aut"]', ns).text

输出:

John Doe