1
<?xml version="1.0" encoding="utf-8"?> 
<Report p1:schemaLocation="TemplateXXX http://localhost?language=en" Name="TemplateXXX" xmlns:p1="http://www.w3.org/2001/XMLSchema-instance" xmlns="TemplateXXX"> 
   <HEADER attr1="one" attr2="two" /> 
   <Table filename="12345.pdf"> 
      <left> 
         <details> 
            <item/> 
            <item/> 
         </details> 
      </left> 
      <right> 
         <details> 
            <item/> 
            <item/> 
         </details> 
      </right> 
   </Table> 
</Report> 

I'm running into a strange problem when trying to query elements and attributes in an xml document where a namespace is in the xml.

When I try to query the document to get the header element with the following xpath query I consistantly get null results

XDocument root = XDocument.Load(filePath);
var element = root.XPathSelectElement("/Report/HEADER");

This always returns null however the moment I remove the namespace from the document the query returns the exepcted element.

What is it that I'm getting wrong as I'm getting some what frustrated.

edit: updated xml to valid xml

Marqueone
  • 1,165
  • 2
  • 14
  • 33
  • 2
    `/HEADER` shouldn't work anyway surely, as it's expecting the *root* element to be HEADER, when it's actually Report. Do you *have* to use XPath? In my experience querying is a lot more readable using LINQ to XML directly - especially when namespaces are involved. – Jon Skeet Sep 30 '11 at 15:34

1 Answers1

2

I would personally recommend that you didn't do this with XPath, but you can if you really want. Here's a short but complete program which works with your sample XML, after I'd fixed it up (it isn't valid XML at the moment... please try to provide working examples next time):

using System;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

class Test
{
    static void Main()
    {
        var doc = XDocument.Load("test.xml");
        var manager = new XmlNamespaceManager(new NameTable());
        manager.AddNamespace("foo", "TemplateXXX");

        var query = doc.XPathSelectElement("/foo:Report/foo:HEADER", manager);
        Console.WriteLine(query);
    }
}

In a normal LINQ to XML query you'd just use:

XNamespace ns = "TemplateXXX";
XElement header = doc.RootElement.Element(ns + "HEADER");

No need for a namespace manager etc.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • No, there's no requirement to use xpath, I just find it easier to work with than linq-to-xml at times. Correct me if I'm wonrg, but I'm under the impression that even though you have a namespace in your xml you don't have to include the nsmaepace as part of the element query. – Marqueone Sep 30 '11 at 16:15
  • @codejam: You're wrong :) If the XML element has a namespace, then a query of `foo.Element(localName)` will *not* find it. Fortunately LINQ to XML makes it *really* easy to specify a fully qualified name, as shown in my example. – Jon Skeet Sep 30 '11 at 16:18