0

我正在尝试从 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

但是当我运行该页面时,我没有得到任何结果页面是空的......我做错了什么?

4

2 回答 2

1

根据您向我们展示的 XML <results><trackmatches><track>不在命名空间中。但是您正试图在 opensearch 命名空间中找到它们。即使<results>有命名空间声明,也只有使用opensearch:命名空间前缀的元素(或属性)实际上在该命名空间中。

所以你需要删除命名空间前缀

nodes = doc.SelectNodes("lastfm:results/lastfm:trackmatches/lastfm:track", ns)

即更改为(已删除;见下文)

更新:反映对输入 XML 的编辑:因为顶级元素不是<results>but <lfm>,所以

nodes = doc.SelectNodes("/*/results/trackmatches/track")

另请参阅@Garett 关于尝试像选择属性一样选择子元素的优点。

于 2010-10-22T12:04:02.187 回答
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

要选择track节点,您的XPath查询应该是:

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 和XmlDocument的示例,您可能会发现它们很有用。

于 2010-10-22T13:41:18.977 回答