2010-06-13 25 views
0

首先XML: http://api.chartlyrics.com/apiv1.asmx//GetLyric?lyricId=90&lyricCheckSum=9600c891e35f602eb6e1605fb7b5229e使用Nokogiri從這個XML提要中獲得「LyricArtist」需要什麼?

doc = Nokogiri::XML(open("http://api.chartlyrics.com/apiv1.asmx//GetLyric?lyricId=90&lyricCheckSum=9600c891e35f602eb6e1605fb7b5229e")) 

成功將抓住文檔內容。

此後,我無法進入並獲取數據,我不知道爲什麼?

例如,我希望:

doc.xpath("//LyricArtist") 

踢回的藝術家,但事實並非如此。

我已經嘗試了同樣的事情,與其他飼料,如默認RSS提要,任何WordPress安裝提供,如果我這樣做:

doc.xpath("//link") 

我得到的所有的「鏈接」列表。

我絕對錯過了一些東西,並會喜歡你的輸入。謝謝!!

回答

0

它不喜歡命名空間或模式中的某些東西。

uri = "http://api.chartlyrics.com/apiv1.asmx//GetLyric?LyricId=90&lyricCheckSum=9600c891e35f602eb6e1605fb7b5229e" 
x = open(uri).read() 
x = x.sub(/<.*?>/,'').sub(/<.*?>/,'<GetLyricResult>') 
doc = Nokogiri::XML(x) 
puts doc.xpath('//LyricArtist').text() 
3

XML元素是名稱空間限定的並綁定到http://api.chartlyrics.com/

如果您查看XML你會發現文檔元素有decalred一個命名空間:

<GetLyricResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://api.chartlyrics.com/"> 

爲了匹配綁定到一個命名空間的元素上,你要麼需要聲明綁定一個命名空間前綴到該URI並在XPATH表達式中使用該名稱空間前綴,或使用忽略名稱空間或匹配不同的XPATH表達式。

您可以匹配元素,然後使用local-name()來匹配元素名稱,而不管聲明的名稱空間如何。

//*[local-name()='LyricArtist'] 

如果你想更準確,你可以使用local-name()元素名稱匹配,並且namespace-uri()來聲明命名空間相匹配。

//*[local-name()='LyricArtist' and namespace-uri()='http://api.chartlyrics.com/'] 

第二個例子將阻止對被結合到不同的命名空間具有相同local-name()元件匹配。對於這個特定的實例可能不是問題,但是應該注意。命名空間用於唯一地限定節點,並允許不同的詞彙表使用相同的「名稱」進行某些操作,而不必擔心衝突。

+0

Mads, 非常感謝您花時間向我解釋這一點。 我現在有作業,需要閱讀XML/Namespacing,因爲我覺得這應該對我來說很明顯,事實並非如此。 雖然我確實有一個額外的問題; Nokogiri對我在這裏想要做的事情有好處? 基於我的研究,我發現Nokogiri比大多數其他庫(特定於XML解析)更快,我很喜歡大部分的語法。 其他建議? – 2010-06-14 17:57:44

+0

的Mads, 我發現這個工程太: doc.xpath( '//的xmlns:LyricArtist') 原因是在這裏:http://tenderlovemaking.com/2009/04/23/namespaces-in-xml/ 檢查「獎金回合」。 Mads,再一次,非常感謝你 – 2010-06-14 18:18:02

+0

如果這個「獎金輪」的語法工作,去吧。它的語法較短,編寫起來更容易。只要你明白命名空間是什麼以及命名空間前綴是如何工作的,那麼你就可以準備什麼時候它可能很重要,以及如何處理它。 – 2010-06-15 00:50:07