2016-12-15 1 views
0

Ich möchte Knoten eines XML-Dokuments mit XPath auswählen. Es funktioniert jedoch nicht, wenn das XML-Dokument XML-Namespaces enthält. Wie kann ich unter Berücksichtigung der Namespaces nach Knoten mit XPath suchen?Wählen Sie Knoten mit XPath, wenn das XML-Dokument Namespaces enthält.

Das ist mein XML-Dokument (vereinfacht):

<ComponentSettings xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Company.Product.Components.Model"> 
    <Created xmlns="http://schemas.datacontract.org/2004/07/Company.Configuration">2016-12-14T10:29:28.5614696+01:00</Created> 
    <LastLoaded i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/Company.Configuration" /> 
    <LastSaved xmlns="http://schemas.datacontract.org/2004/07/Company.Configuration">2016-12-14T16:31:37.876987+01:00</LastSaved> 
    <RemoteTracer> 
    <TraceListener> 
     <Key>f987d7bb-9dea-49b4-a689-88c4452d98e3</Key> 
     <Url>http://192.168.56.1:9343/</Url> 
    </TraceListener> 
    </RemoteTracer> 
</ComponentSettings> 

ich alle URL-Tags eines Tracelistener-Tag eines RemoteTracer Tag erhalten möchten. Dies ist, wie ich sie bekommen, aber dies nur funktionieren, wenn das XML-Dokument Namespaces nicht verwenden:

componentConfigXmlDocument = new XmlDocument(); 
componentConfigXmlDocument.LoadXml(myXmlDocumentCode); 
var remoteTracers = componentConfigXmlDocument.SelectNodes("//RemoteTracer/TraceListener/Url"); 

Derzeit meine Abhilfe ist, alle Namespaces aus dem XML-raw String mit regulärem Ausdruck zu entfernen, bevor dem Laden XML. Dann funktioniert meine SelectNodes() gut. Aber das ist keine richtige Lösung.

+0

Mögliche Duplikat [mit XPath Mit Standard-Namespace in C#] (http: // Stackoverflow .com/questions/585812/using-xpath-mit-default-namespace-in-c-sharp) –

+0

Es gibt 1000 Antworten auf diese Frage auf StackOverflow. –

Antwort

1

Sie haben hier zwei Namespaces. Zunächst ist

http://schemas.datacontract.org/2004/07/Company.Product.Components.Model 

Wurzelelement (ComponentSettings), RemoteTracer und alles darunter zu diesem Namensraum gehört. Zweiter Namespace ist

http://schemas.datacontract.org/2004/07/Company.Configuration 

Created, LastLoaded und Saved zu ihr gehören.

Um den Knoten zu erhalten, den Sie benötigen, müssen Sie alle Elemente in Ihrer xpath-Abfrage mit ihren jeweiligen Namespace-Präfixen voranstellen. Mapping dieser Präfixe tatsächlichen Namespaces Sie wie folgt tun:

var componentConfigXmlDocument = new XmlDocument();    
componentConfigXmlDocument.LoadXml(File.ReadAllText(@"G:\tmp\xml.txt")); 
var ns = new XmlNamespaceManager(componentConfigXmlDocument.NameTable); 
ns.AddNamespace("model", "http://schemas.datacontract.org/2004/07/Company.Product.Components.Model"); 
ns.AddNamespace("config", "http://schemas.datacontract.org/2004/07/Company.Configuration"); 

Und dann Abfrage wie folgt:

var remoteTracers = componentConfigXmlDocument.SelectNodes("//model:RemoteTracer/model:TraceListener/model:Url", ns); 
+0

Danke das funktioniert. Ich habe viel versucht und nach Beispielen gesucht, die zu meiner Ausgangssituation passen, aber ich habe keinen gefunden. Aber das funktioniert. Vielen Dank! – rittergig

Verwandte Themen