2009-07-08 6 views
11

Einfache Frage, ich möchte nur den Text aus dem <Template> Tag auswählen. Hier ist, was ich habe, aber der Xpath passt nichts.Wie wählt man Knoten mit XPath in C#?

public static void TestXPath() 
{ 
    string xmlText = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"; 
    xmlText += "<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">"; 
    xmlText += "<Template>Normal</Template> <TotalTime>1</TotalTime> <Pages>1</Pages> <Words>6</Words>"; 
    xmlText += "</Properties>"; 

    XmlDocument xmlDoc = new XmlDocument(); 
    xmlDoc.Load(new System.IO.StringReader(xmlText)); 

    foreach (XmlNode node in xmlDoc.SelectNodes("//Template")) 
    { 
     Console.WriteLine("{0}: {1}", node.Name, node.InnerText); 
    } 
} 

Antwort

24

Sie benötigen ein XmlNamespaceManager zu verwenden, da das Template-Element in einem Namespace ist:

XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.Load(new System.IO.StringReader(xmlText)); 
XmlNamespaceManager manager = new XmlNamespaceManager(xmlDoc.NameTable); 
manager.AddNamespace("ns", 
    "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"); 

foreach (XmlNode node in xmlDoc.SelectNodes("//ns:Template", manager)) 
{ 
    Console.WriteLine("{0}: {1}", node.Name, node.InnerText); 
} 
7

Das ist ein Namespace-Problem ist; Sie müssen die Namenstabelle abrufen, einen Alias ​​auswählen und diesen in Ihrer Abfrage verwenden. Oder versuchen Sie (in diesem Fall) GetElementsByTagName.

XmlNamespaceManager mgr = new XmlNamespaceManager(xmlDoc.NameTable); 
mgr.AddNamespace("x", 
    "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"); 
foreach (XmlNode node in xmlDoc.SelectNodes("//x:Template", mgr)) 
{ 
    Console.WriteLine("{0}: {1}", node.Name, node.InnerText); 
} 

Oder:

foreach (XmlNode node in xmlDoc.GetElementsByTagName("Template")) 
{ 
    Console.WriteLine("{0}: {1}", node.Name, node.InnerText); 
} 
+0

Ich hatte keine Ahnung, dass Sie einen beliebigen Alias ​​auswählen mussten, um XPath-Abfragen auf diese Weise korrekt aufzulösen! Danke für die Info Marc. –

4

hier Ihr XPath-Ausdruck erfordert eine Namespace Auflösung. Sie müssen einen XmlNamespaceManager instanziieren und in Ihren SelectNodes verwenden.

sollte diese Probe

arbeiten
public static void TestXPath() 
    { 
     string xmlText = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"; 
     xmlText += "<Properties xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\">"; 
     xmlText += "<Template>Normal</Template> <TotalTime>1</TotalTime> <Pages>1</Pages> <Words>6</Words>"; 
     xmlText += "</Properties>"; 

     XmlDocument xmlDoc = new XmlDocument(); 
     xmlDoc.Load(new System.IO.StringReader(xmlText)); 

     XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable); 
     nsmgr.AddNamespace("res", "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"); 

     foreach (XmlNode node in xmlDoc.SelectNodes("//res:Template", nsmgr)) 
     { 
      Console.WriteLine("{0}: {1}", node.Name, node.InnerText); 
     } 
    } 

Sie auch die Standard-Namespace

string s = xmlDoc.DocumentElement.GetNamespaceOfPrefix(""); 
nsmgr.AddNamespace("ns", s); 
2

Warum Sie den Namespace hier ohnehin durch die Verwendung und schreiben müssen, bekommen Sie? nur loswerden diese

xmlns=\"http://schemas.openxmlformats.org/officeDocument/2006/extended-properties\" 
xmlns:vt=\"http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes\" 

und Ihre Auswahl wird funktionieren.

Verwandte Themen