2010-08-22 89 views
4

我需要解析的XML樣式表:Nokogiri可以搜索「?xml-stylesheet」標籤嗎?

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="/templates/xslt/inspections/disclaimer_en.xsl"?> 

使用引入nokogiri我想:

doc.search("?xml-stylesheet").first['href'] 

,但我得到的錯誤:

`on_error': unexpected '?' after '' (Nokogiri::CSS::SyntaxError) 

回答

2

引入nokogiri無法搜索標記,是XML處理指令。您可以像這樣訪問它們:

doc.children[0] 
+0

-1這對於我在Nokogiri 1.5.5上不適用:'p Nokogiri.XML('<?xml version =「1.0」encoding =「UTF-8」?>').children [0]# =>#' – Phrogz 2012-08-28 15:57:06

+0

兩年前確實有效,但Nokogiri可以從內部改變。當然,在我寫這個答案的時候,我測試了我的代碼。 – 2012-08-28 17:58:08

+0

我真的相信你。我在內部努力解決舊問題的答案,這些問題顯然是正確的,但不再有效。我目前的看法是,如果存在替代的正確答案,應該降低這些答案。這不是我打算懲罰你(當然不是!),而是要表明答案(不再)是有幫助的。 – Phrogz 2012-08-28 21:00:44

1

這不是一個XML元素;這是一個XML "Processing Instruction"。這就是爲什麼你找不到你的查詢。爲了找到它,你想:

# Find the first xml-stylesheet PI 
xss = doc.at_xpath('//processing-instruction("xml-stylesheet")') 

# Find every xml-stylesheet PI 
xsss = doc.xpath('//processing-instruction("xml-stylesheet")') 

看在行動:

require 'nokogiri' 
xml = <<ENDXML 
    <?xml version="1.0" encoding="UTF-8"?> 
    <?xml-stylesheet type="text/xsl" href="/templates/disclaimer_en.xsl"?> 
    <root>Hi Mom!</root> 
ENDXML 
doc = Nokogiri.XML(xml) 
xss = doc.at_xpath('//processing-instruction("xml-stylesheet")') 
puts xss.name  #=> xml-stylesheet 
puts xss.content #=> type="text/xsl" href="/templates/disclaimer_en.xsl" 

因爲處理指令不是元素,它不具有的屬性;例如,你不能要求xss['type']xss['href'];如果您願意,您將需要將內容解析爲元素。要做到這一點的方法之一是:

class Nokogiri::XML::ProcessingInstruction 
    def to_element 
    document.parse("<#{name} #{content}/>") 
    end 
end 

p xss.to_element['href'] #=> "/templates/disclaimer_en.xsl" 

注有在引入nokogiri或libxml2的存在a bug這將導致XML Declaration文檔中顯示爲Processing Instruction如果有至少一個字符(可以是一個空格)之前<?xml。這就是爲什麼在上面我們特別搜索名稱爲xml-stylesheet的加工說明。

編輯:XPath表達式processing-instruction()[name()="foo"]等效於表達processing-instruction("foo")。正如XPath 1.0 spec描述:

The processing-instruction() test may have an argument that is Literal; in this case, it is true for any processing instruction that has a name equal to the value of the Literal.

我已經編輯上面的答案,使用較短的格式。

+0

請注意,如果您知道每個PI都位於文檔的根目錄 - 不是文檔深處其他元素的子項,則可以使用xpath('/ processing-instruction( 「xml-stylesheet」)'。 – Phrogz 2012-09-04 23:09:39

+0

好的解釋。解決了我的問題! – 2012-09-06 09:31:58