2009-07-08 17 views
11

Domanda semplice, voglio solo selezionare il testo dal tag <Modello>. Ecco cosa ho, ma l'Xpath non corrisponde a nulla.Come selezionare i nodi con 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); 
    } 
} 

risposta

24

è necessario utilizzare un XmlNamespaceManager perché l'elemento del modello è in uno spazio dei nomi:

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

Questo è un problema di spazio dei nomi; è necessario ottenere la tabella dei nomi, scegliere un alias e utilizzarlo nella query. O forse (in questo caso) prova 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); 
} 

Oppure:

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

Non avevo idea che dovessi scegliere un alias arbitrario per risolvere correttamente le query XPath in questo modo! Grazie per l'informazione Marc. –

4

Qui la vostra espressione XPath richiede una risoluzione dello spazio dei nomi. devi installare un XmlNamespaceManager e utilizzarlo in SelectNodes.

questo campione dovrebbe funzionare

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); 
     } 
    } 

si può anche ottenere lo spazio dei nomi predefinito utilizzando e scrivere

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

Perché avete bisogno di spazio dei nomi qui comunque? liberati di questi

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

e la selezione funzionerà.

Problemi correlati