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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.