麻烦使用XPath

时间:2011-04-01 23:02:45

标签: c# xpath

我正在尝试解析Spotify查找寄存器,但经过多次尝试后,我在此尝试作为最后的手段。

相关XML: http://ws.spotify.com/lookup/1/?uri=http://open.spotify.com/track/3aKJVWH2QOsaMtiCLxYHZX

相关代码:

var response = streamReader.ReadToEnd();
xml.LoadXml(response);
var name = xml.SelectSingleNode("//track/name").InnerText;
var artist = xml.SelectSingleNode("//track/artist/name").InnerText;
var album = xml.SelectSingleNode("//track/album/name").InnerText;
var length = xml.SelectSingleNode("//track/length").InnerText;

相关调试:http://screencast.com/t/yDc8f7Wyzv9P

5 个答案:

答案 0 :(得分:3)

我的猜测是你应该在你的XPath表达式前面加上,或者省略默认命名空间:

http://msdn.microsoft.com/en-us/library/h0hw012b.aspx#Y1372

陈述:

请注意 如果XPath表达式不包含前缀,则假定名称空间URI是空名称空间。如果您的XML包含默认命名空间,您仍必须向XmlNamespaceManager添加前缀和命名空间URI;否则,您将无法选择节点。有关更多信息,请参阅使用XPath导航选择节点。

按照你的例子:

 XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
 nsmgr.AddNamespace("ns", "http://http://www.spotify.com/ns/music/1");
 var name = xml.SelectSingleNode("//ns:track/ns:name", nsmgr);

答案 1 :(得分:1)

这是一个FAQ :您需要在XPath表达式中注册名称空间

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ns", "http://www.spotify.com/ns/music/1");
var name = xml.SelectSingleNode("/ns:track/ns:name", nsmgr); 

另请注意,当模式众所周知时,不需要启动//运算符。

答案 2 :(得分:0)

Quoth the documentation

  

如果XPath表达式不包含前缀,则假定名称空间URI是空名称空间。如果您的XML包含默认命名空间,您仍必须向XmlNamespaceManager添加前缀和命名空间URI;否则,您将无法选择任何节点。

XML文档确实有一个默认命名空间,特别是http://www.spotify.com/ns/music/1。您需要为xpath查询提供前缀和名称空间URI。

答案 3 :(得分:0)

为什么不使用LINQ to XML让您的生活更轻松?

答案 4 :(得分:0)

决定尝试另一种方法,感谢Windcape我找到了XmlSerializer

var serializer = new XmlSerializer(typeof(Track));
var track = (Track)serializer.Deserialize(streamReader);

var time = TimeSpan.FromSeconds(track.length);

var ircResponse = string.Format("{0} - {1} ({2}) | {3}min {4}sec | {5}% popular",
  track.artist.name,
  track.name,
  track.album.name,
  time.TotalMinutes, time.Seconds,
  Math.Round(track.popularity * 100, 0));

CommandHandler.Msg(chan, ircResponse);