Un modo è quello di utilizzare le estensioni + NameSpaceManager.
Il codice è in VB ma è davvero facile da tradurre in C#.
Imports System.Xml
Imports System.Runtime.CompilerServices
Public Module Extensions_XmlHelper
'XmlDocument Extension for SelectSingleNode
<Extension()>
Public Function _SelectSingleNode(ByVal XmlDoc As XmlDocument, xpath As String) As XmlNode
If XmlDoc Is Nothing Then Return Nothing
Dim nsMgr As XmlNamespaceManager = GetDefaultXmlNamespaceManager(XmlDoc, "x")
Return XmlDoc.SelectSingleNode(GetNewXPath(xpath, "x"), nsMgr)
End Function
'XmlDocument Extension for SelectNodes
<Extension()>
Public Function _SelectNodes(ByVal XmlDoc As XmlDocument, xpath As String) As XmlNodeList
If XmlDoc Is Nothing Then Return Nothing
Dim nsMgr As XmlNamespaceManager = GetDefaultXmlNamespaceManager(XmlDoc, "x")
Return XmlDoc.SelectNodes(GetNewXPath(xpath, "x"), nsMgr)
End Function
Private Function GetDefaultXmlNamespaceManager(ByVal XmlDoc As XmlDocument, DefaultNamespacePrefix As String) As XmlNamespaceManager
Dim nsMgr As New XmlNamespaceManager(XmlDoc.NameTable)
nsMgr.AddNamespace(DefaultNamespacePrefix, XmlDoc.DocumentElement.NamespaceURI)
Return nsMgr
End Function
Private Function GetNewXPath(xpath As String, DefaultNamespacePrefix As String) As String
'Methode 1: The easy way
Return xpath.Replace("/", "/" + DefaultNamespacePrefix + ":")
''Methode 2: Does not change the nodes with existing namespace prefix
'Dim Nodes() As String = xpath.Split("/"c)
'For i As Integer = 0 To Nodes.Length - 1
' 'If xpath starts with "/", don't add DefaultNamespacePrefix to the first empty node (before "/")
' If String.IsNullOrEmpty(Nodes(i)) Then Continue For
' 'Ignore existing namespaces prefixes
' If Nodes(i).Contains(":"c) Then Continue For
' 'Add DefaultNamespacePrefix
' Nodes(i) = DefaultNamespacePrefix + ":" + Nodes(i)
'Next
''Create and return then new xpath
'Return String.Join("/", Nodes)
End Function
End Module
E per usarlo:
Imports Extensions_XmlHelper
......
Dim FileXMLTextReader As New XmlTextReader(".....")
FileXMLTextReader.WhitespaceHandling = WhitespaceHandling.None
Dim xmlDoc As XmlDocument = xmlDoc.Load(FileXMLTextReader)
FileXMLTextReader.Close()
......
Dim MyNode As XmlNode = xmlDoc._SelectSingleNode("/Document/FirstLevelNode/SecondLevelNode")
Dim MyNode As XmlNodeList = xmlDoc._SelectNodes("/Document/FirstLevelNode/SecondLevelNode")
......
fonte
2016-04-11 13:37:51
Due problemi con la soluzione di annakata: 1. E 'brutto, 2. In questo caso può essere utilizzata ma fornirà risultati sbagliati se un elemento 'ProjectGuid' appartiene a più di un namespace e vogliamo gli elementi solo da un singolo spazio dei nomi. Le soluzioni che utilizzano NamespaceManager sono migliori –
Il motore XPath deve disporre del contesto statico corretto contenente i collegamenti tra prefissi e URI NS da utilizzare durante la valutazione di espressioni o non sarà possibile fare riferimento a roba all'interno di spazi dei nomi. Questo è ciò che fa @Teun. – lkuty