Ваши xpaths немного шаткие; вы на самом деле не рассматриваете документ как набор иерархических узлов. Если это помогает, думайте об этом как о путях к файлам и папках. Получите «папку» по определенному пути и извлеките ее атрибуты / внутренние тексты (файлы), но относитесь к ней относительно того, где вы находитесь
For Each node As XmlNode In doc.SelectNodes("/dmodule/content/faultIsolation/faultIsolationProcedure")
Dim idAtt = node.Attributes("id").Value
Dim desc As String = node.SelectSingleNode("faultDescr/descr").InnerText
Dim applicIDAtt = node.Attributes("applicRefId").Value
Теперь вы действительно не опубликовали полезно большой XML образец документа для меня, чтобы точно определить, на каком уровне иерархии узлы повторяются, поэтому я предположил, что это так:
<dmodule>
<content>
<faultIsolation>
<faultIsolationProcedure applicRefId=""Software"" id=""tree1"">
<fault faultCode="" ""/>
<faultDescr>
<descr>This nodes description</descr>
</faultDescr>
</faultIsolationProcedure>
<faultIsolationProcedure applicRefId=""Software2"" id=""tree2"">
<fault faultCode="" ""/>
<faultDescr>
<descr>This nodes description2</descr>
</faultDescr>
</faultIsolationProcedure>
</faultIsolation>
</content>
</dmodule>
1 faultIsolation
узел имеет несколько faultIsolationprocedure
узлов
Вот полный код, который вы можете вставить на какой-нибудь сайт vb. net fiddle и запустить, чтобы осветить проблему. Прочитайте полный код, включая мои комментарии. Я поместил свой код выше, а затем ваш код с комментарием к каждому, в комментариях в VB:
Imports System
Imports System.Xml
Public Module Module1
Public Sub Main()
Dim doc As New XmlDocument()
doc.LoadXml("<dmodule>
<content>
<faultIsolation>
<faultIsolationProcedure applicRefId=""Software"" id=""tree1"">
<fault faultCode="" ""/>
<faultDescr>
<descr>This nodes description</descr>
</faultDescr>
</faultIsolationProcedure>
<faultIsolationProcedure applicRefId=""Software2"" id=""tree2"">
<fault faultCode="" ""/>
<faultDescr>
<descr>This nodes description2</descr>
</faultDescr>
</faultIsolationProcedure>
</faultIsolation>
</content>
</dmodule>")
'#####################################
' my way
'#####################################
'treat /dmodule/content/faultIsolation/faultIsolationProcedure as a collection of nodes, do each one
For Each node As XmlNode In doc.SelectNodes("/dmodule/content/faultIsolation/faultIsolationProcedure")
'pull attribute by name
Dim idAtt = node.Attributes("id").Value
'pull a sub node relative to the current node, not the document root
Dim desc As String = node.SelectSingleNode("faultDescr/descr").InnerText
'pull attribute by name
Dim applicIDAtt = node.Attributes("applicRefId").Value
Console.WriteLine(idAtt)
Console.WriteLine(desc)
Console.WriteLine(applicIDAtt)
Next
Console.WriteLine("##############")
'#####################################
' your way
'#####################################
For Each node As XmlNode In doc.SelectNodes("/dmodule/content/faultIsolation/faultIsolationProcedure/faultDescr/descr")
'well it sort of works for the first one, because // is always the document root
'in xpath, not the current node. The node you're looking at still knows of the
'document and if you ask it to search for an xpath starting with // you're NOT
'searching from the current node as a start point, but the doc root. this is why
'you keep getting the same node, because the code goes back to the doc root and
'pulls the first child node, which is always the same node!
Dim idAtt = node.SelectSingleNode("//faultIsolationProcedure/@id").InnerText
'this is OK - it works relative to the node you're currently on in the foreach
'and it does return different descriptions each time
Dim desc As String = node.InnerText
'Again, this xpath starts with / which is "from the doc root" not "from the current node"
'-because this doesn't have a double slash it has to be an exact path from the doc root
'which is IS - it's a valid path and it might well be that there are lots of nodes
'in the document with this path, but your call to selectsinglenode will only
'give you the first encountered node in the document, so its always the same node..
Dim applicIDAtt = node.SelectSingleNode("/dmodule/content/faultIsolation/faultIsolationProcedure/@applicRefId").InnerText
Console.WriteLine(idAtt)
Console.WriteLine(desc)
Console.WriteLine(applicIDAtt)
Next
End Sub
End Module
Помните. Если у вас есть такая файловая система:
c:\temp\my\path\file.txt
Вы можете сделать это:
CD c:\temp\my
И вы будете в папке my
, и вы можете обратиться к файл относительно или абсолютно:
notepad path\file.txt
notepad c:\temp\my\path\file.txt
XPath ничем не отличается; если вы начинаете путь с sla sh, он «из do c root» независимо от текущего узла, как если бы вы начинали путь к файлу с c:\
, это с диска root независимо от текущего каталога