2012-12-17 72 views
4

如果祖先節點定義命名空間中定義的節點,我可以使用它們:如何搜索與命名空間在同一個節點

> 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是不得已而爲之。

回答

6

要以編程方式收集所有名稱空間,請使用Document#collect_namespaces

xml = Nokogiri::XML(xmldata) 

ns = xml.collect_namespaces 

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

輸出:

John Doe 
+0

我知道,我們可以從字面上指定的命名空間,如果我們事先知道的命名空間,但如何讓這些命名空間編程? – hiroshi

+0

我已經更新了代碼示例來執行此操作。 –

+0

謝謝!我沒有注意到'Nokogiri :: XML#collect_namespaces'這個方法。 – hiroshi