2009-07-08 78 views
11

簡單的問題,我只想從<模板>標籤中選擇文本。這是我的,但Xpath不匹配任何東西。如何在C#中使用XPath選擇節點?

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

回答

24

你需要使用一個XmlNamespaceManager因爲模板元素是一個命名空間:

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

這是一個命名空間的問題;您需要獲取名稱表,選擇一個別名,然後在查詢中使用它。或者可能(在這種情況下)嘗試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); 
} 

或者:

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

我不知道你必須選擇一個任意的別名來以這種方式正確解析XPath查詢!感謝Marc的信息。 – 2010-04-29 18:56:48

4

這裏您的XPath表達式需要命名空間分辨率。你必須實例化一個XmlNamespaceManager並在你的SelectNodes中使用它。

這個樣本應該工作

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

你也可以得到默認命名空間使用和編寫

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

爲什麼你需要在這裏的命名空間呢?只是擺脫這些

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

和您的選擇將工作。