12

Simple question, I just want to select the text from the <Template> tag. Here's what I have, but the Xpath doesn't match anything.

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

4 Answers 4

27

You need to use an XmlNamespaceManager because the Template element is in a namespace:

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); } 
Sign up to request clarification or add additional context in comments.

Comments

7

That is a namespace issue; you need to get the name-table, pick an alias, and use that in your query. Or perhaps (in this case) try 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); } 

Or:

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

1 Comment

I had no idea you had to pick an arbitrary alias to properly resolve XPath queries in this manner! Thanks for the info Marc.
4

Here your xpath expression requires a namespace resolution. you have to instanciate a XmlNamespaceManager and use it in your SelectNodes.

this sample should work

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

you can also get the default namespace by using and write

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

Comments

2

Why do you need the namespace here anyway? just get rid of these

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

and your selection will work.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.