ASP.NET Select XML 节点基于子元素中的属性值
ASP.NET Select XML nodes based on attribute value in child element
我正在尝试遍历下面的 XML 并找到所有 entry
元素,其中基础 category
元素的值 collection
为 thr term
属性。下面的例子中有 2 个。然后为那些获取 link
元素上的 href
属性的值。
但是,我似乎找不到合适的 select 或:
<feed xmlns="http://www.w3.org/2005/Atom">
<title>demo</title>
<id>urn:uuid:071d9650-ae6c-11e7-8f1a-0800200c9a66</id>
<link rel="self" href="https://test.com/atom/index.xml"/>
<updated>2017-10-11T14:37:33+02:00</updated>
<author>
<name>Test</name>
<uri>http://www.test.com</uri>
</author>
<generator version="1.8">Agent</generator>
<entry>
<title>YDEMO</title>
<id>urn:uuid:15f44340-ae6c-11e7-8f1a-0800200c9a66</id>
<category term="collection"/>
<published>2017-10-11T13:41:53+02:00</published>
<updated>2017-10-11T14:37:33+02:00</updated>
<link rel="alternate" href="https://www.myurl.com" type="text/xml"/>
<mcp:projectScenario xmlns:mcp="http://webservice.yes-co.nl/3mcp/1.5/atom-extension">NBvh</mcp:projectScenario>
</entry>
<entry>
<title>DEMO 2</title>
<id>urn:uuid:25f44340-ae6c-11e7-8f1a-0800200c9a00</id>
<category term="collection"/>
<published>2017-10-11T13:42:53+02:00</published>
<updated>2017-10-11T14:38:33+02:00</updated>
<link rel="alternate" href="https://www.myurl2.com" type="text/xml"/>
<mcp:projectScenario xmlns:mcp="http://webservice.yes-co.nl/3mcp/1.5/atom-extension">BBvh</mcp:projectScenario>
</entry>
<entry>
<title>photo</title>
<id>12</id>
<category term="metadata"/>
<updated>2016-10-11T14:38:33+02:00</updated>
<link rel="alternate" href="https://www.myurl2.com" type="text/xml"/>
</entry>
<entry
xmlns:mcp="http://webservice.yes-co.nl/3mcp/1.5/atom-extension">
<title>No title</title>
<id>urn:uuid:6d65c57f-621f-4c15-8a1d-5dc967423d5d</id>
<category term="media"/>
<published>2017-10-11T13:39:43+02:00</published>
<updated>2017-10-11T13:39:43+02:00</updated>
<link
xmlns:mcp="http://webservice.yes-co.nl/3mcp/1.5/atom-extension" rel="related" href="https://webservice.yes-co.com/3mcp/1.5/15f44340-ae6c-11e7-8f1a-0800200c9a66/media/6d65c57f-621f-4c15-8a1d-5dc967423d5d-large.jpg" type="image/jpg" mcp:mediaFormat="large"/>
</entry>
</feed>
到目前为止,这是我的代码,但即使 data
变量包含上面的 XML,nodeList.Count
行 returns 0 结果:
Dim WC As New WebClient
Dim data As String = WC.DownloadString("http://localhost/index.xml")
Dim indexXML As New XmlDocument
indexXML.LoadXml(data)
Dim mgr As XmlNamespaceManager = New XmlNamespaceManager(indexXML.NameTable)
mgr.AddNamespace("http://www.w3.org/2005/Atom", indexXML.DocumentElement.NamespaceURI)
Dim node As XmlNode
Dim root As XmlNode = indexXML.DocumentElement
Dim nodeList As XmlNodeList = root.SelectNodes("/feed/entry")
'now loop through all elements with "category term=collection" in index.xml
For i As Integer = 0 To nodeList.Count - 1
If nodeList(i).SelectSingleNode("/category/@term=collection") IsNot Nothing Then
LogMessage(nodeList(i).SelectSingleNode("/category/link/@href").Value)
End If
Next i
更新 1
我想要 select 所有 'entry' 元素,其中它有一个带有 term=collection
的类别节点。该部分通过以下语句起作用:indexXML.SelectNodes("/atom:feed/atom:entry[atom:category/@term=""collection""]", mgr)
我想从入口节点开始,然后我想 select 入口子元素 link 的 href 属性(以及将来 entry
的其他子元素)。
但是,none 我在下面尝试的示例中,return href
属性的值。我该如何解决?
我现在有这个:
Dim mgr As XmlNamespaceManager = New XmlNamespaceManager(indexXML.NameTable)
mgr.AddNamespace("atom", "http://www.w3.org/2005/Atom")
Dim root As XmlNode = indexXML.DocumentElement
Dim nodeList As XmlNodeList = indexXML.SelectNodes("/atom:feed/atom:entry[atom:category/@term=""collection""]", mgr)
'now loop through all collections in index.xml
For i As Integer = 0 To nodeList.Count - 1 '1 result found
'NONE OF CALLS BELOW RETURN THE VALUE OF HREF ATTRIBUTE
If nodeList(i).SelectSingleNode("atom:/link/@href", mgr) IsNot Nothing Then
LogMessage(nodeList(i).SelectSingleNode("atom:/link/@href", mgr).Value)
'error: 'atom:/link/@href' has an invalid qualified name.
End If
Next i
更新 2
感谢@Pawel,我能够 select 所有 entry
节点 project
作为 category
节点上 term
属性的值,如下所示:
objectsXML.SelectNodes("/atom:feed/atom:entry[atom:category/@term=""project""]", mgr)
但是,我如何向此 select 添加额外的标准或过滤掉 entry
具有值 NBvh
或 BBvh
节点 [=38] 的节点=]?
更新 3
我向管理器添加了一个额外的命名空间:
mgr.AddNamespace("atom", "http://www.w3.org/2005/Atom")
mgr.AddNamespace("mcp", "http://webservice.yes-co.nl/3mcp/1.5/atom-extension")
但是当我尝试通过 uuid select 媒体元素的 href
属性时,出现错误:Object reference not set to an instance of an object.
我的代码:
objectsXML.SelectSingleNode("/atom:feed/atom:entry[atom:id=""urn:uuid:" + "6d65c57f-621f-4c15-8a1d-5dc967423d5d" + """]/mcp:link/@href", mgr).InnerText
文档使用 http://www.w3.org/2005/Atom
命名空间。您需要将此命名空间绑定到一个 uri 前缀,并在您的 XPath 中使用此前缀。
如果像这样将命名空间绑定到 atom
前缀:
var nsmanager = new XmlNamespaceManager(indexXML.NameTable);
nsmanager.AddNamespace("atom", "http://www.w3.org/2005/Atom");
如果您传递命名空间管理器,您将能够在您的 XPath 表达式中使用此前缀,例如:
indexXML.SelectNodes("/atom:feed/atom:entry[atom:category/@term="collection"]/atom:link/@href", nsmanager)
我正在尝试遍历下面的 XML 并找到所有 entry
元素,其中基础 category
元素的值 collection
为 thr term
属性。下面的例子中有 2 个。然后为那些获取 link
元素上的 href
属性的值。
但是,我似乎找不到合适的 select 或:
<feed xmlns="http://www.w3.org/2005/Atom">
<title>demo</title>
<id>urn:uuid:071d9650-ae6c-11e7-8f1a-0800200c9a66</id>
<link rel="self" href="https://test.com/atom/index.xml"/>
<updated>2017-10-11T14:37:33+02:00</updated>
<author>
<name>Test</name>
<uri>http://www.test.com</uri>
</author>
<generator version="1.8">Agent</generator>
<entry>
<title>YDEMO</title>
<id>urn:uuid:15f44340-ae6c-11e7-8f1a-0800200c9a66</id>
<category term="collection"/>
<published>2017-10-11T13:41:53+02:00</published>
<updated>2017-10-11T14:37:33+02:00</updated>
<link rel="alternate" href="https://www.myurl.com" type="text/xml"/>
<mcp:projectScenario xmlns:mcp="http://webservice.yes-co.nl/3mcp/1.5/atom-extension">NBvh</mcp:projectScenario>
</entry>
<entry>
<title>DEMO 2</title>
<id>urn:uuid:25f44340-ae6c-11e7-8f1a-0800200c9a00</id>
<category term="collection"/>
<published>2017-10-11T13:42:53+02:00</published>
<updated>2017-10-11T14:38:33+02:00</updated>
<link rel="alternate" href="https://www.myurl2.com" type="text/xml"/>
<mcp:projectScenario xmlns:mcp="http://webservice.yes-co.nl/3mcp/1.5/atom-extension">BBvh</mcp:projectScenario>
</entry>
<entry>
<title>photo</title>
<id>12</id>
<category term="metadata"/>
<updated>2016-10-11T14:38:33+02:00</updated>
<link rel="alternate" href="https://www.myurl2.com" type="text/xml"/>
</entry>
<entry
xmlns:mcp="http://webservice.yes-co.nl/3mcp/1.5/atom-extension">
<title>No title</title>
<id>urn:uuid:6d65c57f-621f-4c15-8a1d-5dc967423d5d</id>
<category term="media"/>
<published>2017-10-11T13:39:43+02:00</published>
<updated>2017-10-11T13:39:43+02:00</updated>
<link
xmlns:mcp="http://webservice.yes-co.nl/3mcp/1.5/atom-extension" rel="related" href="https://webservice.yes-co.com/3mcp/1.5/15f44340-ae6c-11e7-8f1a-0800200c9a66/media/6d65c57f-621f-4c15-8a1d-5dc967423d5d-large.jpg" type="image/jpg" mcp:mediaFormat="large"/>
</entry>
</feed>
到目前为止,这是我的代码,但即使 data
变量包含上面的 XML,nodeList.Count
行 returns 0 结果:
Dim WC As New WebClient
Dim data As String = WC.DownloadString("http://localhost/index.xml")
Dim indexXML As New XmlDocument
indexXML.LoadXml(data)
Dim mgr As XmlNamespaceManager = New XmlNamespaceManager(indexXML.NameTable)
mgr.AddNamespace("http://www.w3.org/2005/Atom", indexXML.DocumentElement.NamespaceURI)
Dim node As XmlNode
Dim root As XmlNode = indexXML.DocumentElement
Dim nodeList As XmlNodeList = root.SelectNodes("/feed/entry")
'now loop through all elements with "category term=collection" in index.xml
For i As Integer = 0 To nodeList.Count - 1
If nodeList(i).SelectSingleNode("/category/@term=collection") IsNot Nothing Then
LogMessage(nodeList(i).SelectSingleNode("/category/link/@href").Value)
End If
Next i
更新 1
我想要 select 所有 'entry' 元素,其中它有一个带有 term=collection
的类别节点。该部分通过以下语句起作用:indexXML.SelectNodes("/atom:feed/atom:entry[atom:category/@term=""collection""]", mgr)
我想从入口节点开始,然后我想 select 入口子元素 link 的 href 属性(以及将来 entry
的其他子元素)。
但是,none 我在下面尝试的示例中,return href
属性的值。我该如何解决?
我现在有这个:
Dim mgr As XmlNamespaceManager = New XmlNamespaceManager(indexXML.NameTable)
mgr.AddNamespace("atom", "http://www.w3.org/2005/Atom")
Dim root As XmlNode = indexXML.DocumentElement
Dim nodeList As XmlNodeList = indexXML.SelectNodes("/atom:feed/atom:entry[atom:category/@term=""collection""]", mgr)
'now loop through all collections in index.xml
For i As Integer = 0 To nodeList.Count - 1 '1 result found
'NONE OF CALLS BELOW RETURN THE VALUE OF HREF ATTRIBUTE
If nodeList(i).SelectSingleNode("atom:/link/@href", mgr) IsNot Nothing Then
LogMessage(nodeList(i).SelectSingleNode("atom:/link/@href", mgr).Value)
'error: 'atom:/link/@href' has an invalid qualified name.
End If
Next i
更新 2
感谢@Pawel,我能够 select 所有 entry
节点 project
作为 category
节点上 term
属性的值,如下所示:
objectsXML.SelectNodes("/atom:feed/atom:entry[atom:category/@term=""project""]", mgr)
但是,我如何向此 select 添加额外的标准或过滤掉 entry
具有值 NBvh
或 BBvh
节点 [=38] 的节点=]?
更新 3 我向管理器添加了一个额外的命名空间:
mgr.AddNamespace("atom", "http://www.w3.org/2005/Atom")
mgr.AddNamespace("mcp", "http://webservice.yes-co.nl/3mcp/1.5/atom-extension")
但是当我尝试通过 uuid select 媒体元素的 href
属性时,出现错误:Object reference not set to an instance of an object.
我的代码:
objectsXML.SelectSingleNode("/atom:feed/atom:entry[atom:id=""urn:uuid:" + "6d65c57f-621f-4c15-8a1d-5dc967423d5d" + """]/mcp:link/@href", mgr).InnerText
文档使用 http://www.w3.org/2005/Atom
命名空间。您需要将此命名空间绑定到一个 uri 前缀,并在您的 XPath 中使用此前缀。
如果像这样将命名空间绑定到 atom
前缀:
var nsmanager = new XmlNamespaceManager(indexXML.NameTable);
nsmanager.AddNamespace("atom", "http://www.w3.org/2005/Atom");
如果您传递命名空间管理器,您将能够在您的 XPath 表达式中使用此前缀,例如:
indexXML.SelectNodes("/atom:feed/atom:entry[atom:category/@term="collection"]/atom:link/@href", nsmanager)