用简洁的语法解析 XML
Parse XML with succint syntax
在我的应用程序中,我正在从一种网络服务转换到另一种网络服务。我收到 XML 响应 XmlDocument
。我正在尝试获取文档中的特定节点。我知道我正在寻找的节点只会有一个实例。之前的实现者能够准确地得到他想要的东西:
XmlNode node = xmlDoc.SelectSingleNode("//result/geometry/location/lat/text()");
我正在尝试对我的回复做同样的事情,但总是返回 null。我(模糊地)知道他的 XML 反应是什么样子的,也知道我的。但我不能使用他的语法。我得到 null
无论如何。我正在使用更复杂的语句:
XmlNode xmlNode = xmlDoc.GetElementsByTagName("StatusDescription").Item(0);
但是,如您所见,它很难看。而且——更糟糕的是——每当我尝试深入超过一个节点时,我得到的结果是 null:
XmlNode xmlNode = xmlDoc.GetElementsByTagName("/ResourceSets/ResourceSet").Item(0);
我试过在几个地方插入和删除斜线,但都无济于事。 XML 之前的实现者返回的没有什么特别的;只是 XML。但是他可以轻松地到处跳。
这是他的 XML 回复的片段:
<GeocodeResponse>
<status>OK</status>
<result>
<geometry>
<location>
<lat>37.4217550</lat>
<lng>-122.0846330</lng>
</location>
</geometry>
</result>
</GeocodeResponse>
这是我的一个片段:
<Response xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<StatusCode>200</StatusCode>
<StatusDescription>OK</StatusDescription>
<ResourceSets>
<ResourceSet>
<EstimatedTotal>1</EstimatedTotal>
<Resources>
<Location>
...
</Location>
</Resources>
</ResourceSet>
</ResourceSets>
</Response>
知道我怎样才能像他一样轻松穿越 XML 吗?
这里的根本区别是 his XML 没有默认命名空间,而 yours 声明了默认命名空间这里 :
xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1"
顺便说一下,这个主题(针对具有默认命名空间的 XML 的 XPath 查询)以前在 SO 中以各种形式被问过很多次。请注意,声明默认名称空间的元素及其所有没有前缀且没有不同的默认名称空间声明的后代都被视为在上述默认名称空间中。查询命名空间中元素的一种可能方法是使用命名空间管理器将前缀映射到命名空间 uri,然后在 XPath 中正确使用映射的前缀,例如:
var nsManager As New XmlNamespaceManager(new NameTable());
nsManager.AddNamespace("d", "http://schemas.microsoft.com/search/local/ws/rest/v1");
XmlNode xmlNode = xmlDoc.SelectSingleNode("//d:StatusDescription", nsManager);
在我的应用程序中,我正在从一种网络服务转换到另一种网络服务。我收到 XML 响应 XmlDocument
。我正在尝试获取文档中的特定节点。我知道我正在寻找的节点只会有一个实例。之前的实现者能够准确地得到他想要的东西:
XmlNode node = xmlDoc.SelectSingleNode("//result/geometry/location/lat/text()");
我正在尝试对我的回复做同样的事情,但总是返回 null。我(模糊地)知道他的 XML 反应是什么样子的,也知道我的。但我不能使用他的语法。我得到 null
无论如何。我正在使用更复杂的语句:
XmlNode xmlNode = xmlDoc.GetElementsByTagName("StatusDescription").Item(0);
但是,如您所见,它很难看。而且——更糟糕的是——每当我尝试深入超过一个节点时,我得到的结果是 null:
XmlNode xmlNode = xmlDoc.GetElementsByTagName("/ResourceSets/ResourceSet").Item(0);
我试过在几个地方插入和删除斜线,但都无济于事。 XML 之前的实现者返回的没有什么特别的;只是 XML。但是他可以轻松地到处跳。
这是他的 XML 回复的片段:
<GeocodeResponse>
<status>OK</status>
<result>
<geometry>
<location>
<lat>37.4217550</lat>
<lng>-122.0846330</lng>
</location>
</geometry>
</result>
</GeocodeResponse>
这是我的一个片段:
<Response xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<StatusCode>200</StatusCode>
<StatusDescription>OK</StatusDescription>
<ResourceSets>
<ResourceSet>
<EstimatedTotal>1</EstimatedTotal>
<Resources>
<Location>
...
</Location>
</Resources>
</ResourceSet>
</ResourceSets>
</Response>
知道我怎样才能像他一样轻松穿越 XML 吗?
这里的根本区别是 his XML 没有默认命名空间,而 yours 声明了默认命名空间这里 :
xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1"
顺便说一下,这个主题(针对具有默认命名空间的 XML 的 XPath 查询)以前在 SO 中以各种形式被问过很多次。请注意,声明默认名称空间的元素及其所有没有前缀且没有不同的默认名称空间声明的后代都被视为在上述默认名称空间中。查询命名空间中元素的一种可能方法是使用命名空间管理器将前缀映射到命名空间 uri,然后在 XPath 中正确使用映射的前缀,例如:
var nsManager As New XmlNamespaceManager(new NameTable());
nsManager.AddNamespace("d", "http://schemas.microsoft.com/search/local/ws/rest/v1");
XmlNode xmlNode = xmlDoc.SelectSingleNode("//d:StatusDescription", nsManager);