我正在尝试从lastfm Web服务中读取xml节点值,如下所示:
<lfm status="ok">
<results for="stinkfist" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">
<opensearch:Query role="request" searchTerms="stinkfist" startPage="1" />
<opensearch:totalResults>188</opensearch:totalResults>
<opensearch:startIndex>0</opensearch:startIndex>
<opensearch:itemsPerPage>1</opensearch:itemsPerPage>
<trackmatches>
<track>
<name>Stinkfist</name>
<artist>Tool</artist>
<url>http://www.last.fm/music/Tool/_/Stinkfist</url>
<streamable fulltrack="0">1</streamable>
<listeners>290583</listeners>
<image size="small">http://userserve-ak.last.fm/serve/34s/24508457.jpg</image>
<image size="medium">http://userserve-ak.last.fm/serve/64s/24508457.jpg</image>
<image size="large">http://userserve-ak.last.fm/serve/126/24508457.jpg</image>
<image size="extralarge">http://userserve-ak.last.fm/serve/300x300/24508457.jpg</image>
<mbid></mbid>
</track>
</trackmatches>
</results>
</lfm>
在这里搜索并在网上搜索示例后,我发现了一种应该有效的方法:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim doc As XmlDocument
Dim ns As XmlNamespaceManager
Dim nodes As XmlNodeList
doc = New XmlDocument()
doc.Load("http://ws.audioscrobbler.com/2.0/?method=track.search&limit=1&track=stinkfist&artist=tool&api_key=b25b959554ed76058ac220b7b2e0a026")
ns = New XmlNamespaceManager(doc.NameTable)
ns.AddNamespace("lastfm", "http://a9.com/-/spec/opensearch/1.1/")
nodes = doc.SelectNodes("lastfm:results/lastfm:trackmatches/lastfm:track", ns)
Dim str As String = String.Empty
For Each node As XmlNode In nodes
str += node.Attributes("name").InnerText
str += node.Attributes("artist").InnerText
str += node.Attributes("url").InnerText
str += node.Attributes("listeners").InnerText
Next
Response.Write(str)
End Sub
但是当我运行页面时,我没有得到任何结果,页面是空的...... 我做错了什么?
答案 0 :(得分:1)
根据您向我们展示的XML,<results>
,<trackmatches>
和<track>
没有名称空间。但是你试图在opensearch命名空间中找到它们。尽管<results>
具有名称空间声明,但只有使用opensearch:
名称空间前缀的元素(或属性)实际上位于该名称空间中。
因此您需要从
中删除名称空间前缀nodes = doc.SelectNodes("lastfm:results/lastfm:trackmatches/lastfm:track", ns)
即。将其更改为(已删除;请参见下文)
更新:反映对输入XML的修改:由于顶级元素不是<results>
而是<lfm>
,请执行
nodes = doc.SelectNodes("/*/results/trackmatches/track")
另见@ Garett关于尝试选择子元素的好处,就像它们是属性一样。
答案 1 :(得分:1)
我看到了几个问题。
首先,您不需要仅添加名称空间lastfm
opensearch
(如果您需要访问这些元素)。
所以这一行:
ns.AddNamespace("lastfm", "http://a9.com/-/spec/opensearch/1.1/")
会变成:
ns.AddNamespace("opensearch", "http://a9.com/-/spec/opensearch/1.1/")
如果您需要访问opensearch
元素,则可以使用它:
doc.SelectSingleNode("lfm/results/opensearch:totalResults", ns).InnerText
要选择XPath查询应该是track
个节点:
nodes = doc.SelectNodes("/lfm/results/trackmatches/track")
轨道节点没有属性,因此node.Attributes("name").InnerText
将无效。相反,它们具有子元素(节点),因此要获得这些值,您可以这样做:
node.SelectSingleNode("name").InnerText
甚至更短的语法
node("name").InnerText
总而言之,您的程序将类似于以下内容:
Dim doc As XmlDocument
Dim ns As XmlNamespaceManager
Dim nodes As XmlNodeList
doc = New XmlDocument()
doc.Load("http://ws.audioscrobbler.com/2.0/?method=track.search&track=Believe&api_key=b25b959554ed76058ac220b7b2e0a026")
ns = New XmlNamespaceManager(doc.NameTable)
ns.AddNamespace("opensearch", "http://a9.com/-/spec/opensearch/1.1/")
nodes = doc.SelectNodes("/lfm/results/trackmatches/track")
Dim str As String = String.Empty
For Each node As XmlNode In nodes
str += node.SelectSingleNode("name").InnerText
str += node.SelectSingleNode("artist").InnerText
str += node.SelectSingleNode("url").InnerText
str += node.SelectSingleNode("listeners").InnerText
Next
最后,MSDN使用XPath和examples非常好XmlDocument,您可能会发现它很有用。