如果祖先节点定义了名称空间,我可以使用它们:
> 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
的文字命名空间参数是最后的手段。
答案 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