2010-11-13 15 views
33

Ja ładuje ciąg do dokumentu XML, który zawiera następującą strukturę:XmlDocument.SelectSingleNode i Przestrzenie nazw w XML problem

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">     
    <ItemGroup> 
    <Compile Include="clsWorker.cs" />   
    </ItemGroup>  
</Project> 

potem im wszystko do załadunku XmlDocument:

XmlDocument xmldoc = new XmlDocument(); 
xmldoc.LoadXml(Xml); 

wówczas następujący problem występuje:

XmlNode Node = xmldoc.SelectSingleNode("//Compile"); // return null 

po usunięciu atrybutu xmlns z elementu głównego (Projekt) działa dobrze, jak mogę poprawić mój SelectSingleNode, aby zwrócić odpowiedni element?

Odpowiedz

66

należy użyć XmlNamespaceManager w wywołaniu do SelectSingleNode():

XmlNamespaceManager ns = new XmlNamespaceManager(xmldoc.NameTable); 
ns.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003"); 
XmlNode node = xmldoc.SelectSingleNode("//msbld:Compile", ns); 
+0

Czy Dotyczyło to 'SelectNodes'? –

+0

@ T.S., Tak. 'SelectSingleNode (" xpath ")' jest mniej więcej równoznaczne z 'SelectNodes (" xpath ") [0]'. –

+0

Skąd się wzięło 'msbld'? –

16

Zrobione prawo od documentation of SelectSingleNode() on the MSDN:

Uwaga
Jeśli wyrażenie XPath nie zawiera prefiks, to zakłada się, że identyfikator URI przestrzeni nazw jest pustym obszarem nazw. Jeśli plik XML zawiera domyślną przestrzeń nazw , należy dodać prefiks i identyfikator URI przestrzeni nazw do XmlNamespaceManager; w przeciwnym razie nie zostanie wybrany wybrany węzeł. Dla więcej informacji, patrz Select Nodes Using XPath Navigation.

A zaraz po przykładowy kod jest

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); 
nsmgr.AddNamespace("ab", "http://www.lucernepublishing.com"); 
XmlNode book = doc.SelectSingleNode("//ab:book", nsmgr); 

It'snotasifthiswouldbe "hiddenknowledge". ;-)

+0

Łącza ostatniego zdania o wartości 100 punktów! – milesma

2

Ponieważ "ItemGroup" może mieć wiele dzieci "Kompiluj", a Ty specjalnie chcesz "Kompilować" dzieci z "Project/ItemGroup", poniższe zwrócą wszystkie pożądane dzieci "Kompiluj" i nie inne:

XmlDocument projectDoc = new XmlDocument(); 
projectDoc.Load(projectDocPath); 
XmlNamespaceManager ns = new XmlNamespaceManager(projectDoc.NameTable); 
ns.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003"); 
XmlNodeList xnList = projectDoc.SelectNodes(@"/msbld:Project/msbld:ItemGroup/msbld:Compile", ns); 

Należy zauważyć, że specyfikacja przestrzeni nazw msbld: musi poprzedzać poziom każdego węzła.

+0

przegłosowano dla ostrzeżenia o specyfikacji wielu przestrzeni nazw. – Bora

0

W ten sposób nie trzeba podawać nazw:

XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.LoadXml("your xml"); 
XmlNode node = xmlDoc.SelectSingleNode("/*[local-name() = 'Compile']"); 
XmlNode nodeToImport = xmlDoc2.ImportNode(node, true); 
xmlDoc2.AppendChild(nodeToImport); 
Powiązane problemy