uril
uril

Reputation: 183

Why when including the xml root as part of the xpath I get no results

Why when including the xml root as part of the xpath I get no results.

I’m using a simple xpath "/rdf:RDF/channel" on a XElement(see below)

I’m adding all Namespaces toXmlNamespaceManager, but I get no results, it’s like the xpathNavigator is already at the root so it expects a path that starts with /channel.

The code:

        const string rdfFile = @"C:\index.rdf";
        var text = File.ReadAllText(rdfFile);
        XmlReader reader = XmlReader.Create(new StringReader(text));
        XElement doc = XElement.Load(reader);
        XmlNameTable nameTable = reader.NameTable;
        XmlNameTable table = nameTable ?? new NameTable();
        var manager = new XmlNamespaceManager(table);

        manager.AddNamespace(RDFNamespaceName, RDFNamespace);
        manager.AddNamespace(RDFNamespaceName2, RDFNamespace2);
        manager.AddNamespace(RDFNamespaceName3, RDFNamespace3);
        manager.AddNamespace(RDFNamespaceName4, RDFNamespace4);
        manager.AddNamespace(RDFNamespaceName5, RDFNamespace5);
        manager.AddNamespace(RDFNamespaceName6, RDFNamespace6);
        manager.AddNamespace(RDFNamespaceName7, RDFNamespace7);

    var res = doc.XPathSelectElements(RDFXpath, manager);

    private const string RDFXpath = "/rdf:RDF/channel";


    private const string RDFNamespaceName = "rdf";

    private const string RDFNamespace = @"http://www.w3.org/1999/02/22-rdf-syntax-ns#";

    private const string RDFNamespaceName2 = "";

    private const string RDFNamespace2 = @"http://purl.org/rss/1.0/";

    private const string RDFNamespaceName3 = "cc";

    private const string RDFNamespace3 = @"http://web.resource.org/cc/";

    private const string RDFNamespaceName4 = "content";

    private const string RDFNamespace4 = @"http://purl.org/rss/1.0/modules/content/";

    private const string RDFNamespaceName5 = "admin";

    private const string RDFNamespace5 = @"http://webns.net/mvcb/";

    private const string RDFNamespaceName6 = "sy";

    private const string RDFNamespace6 = @"http://purl.org/rss/1.0/modules/syndication/";

    private const string RDFNamespaceName7 = "dc";

    private const string RDFNamespace7 = @"http://purl.org/dc/elements/1.1/";

Part of the xml:

  <?xml version="1.0" encoding="utf-8" ?> 
- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:cc="http://web.resource.org/cc/" xmlns="http://purl.org/rss/1.0/">
- <channel rdf:about="http://blogs.charlotte.com/panthers/">
  <title>Inside the Panthers</title> 

...

Upvotes: 3

Views: 266

Answers (2)

uril
uril

Reputation: 183

It seems that the problem(in addition to the problem Alexei found) is due to the difference between XElement and XDocument regarding the Root, the xpath I use works if I use XDocument but not if I use XElement, see:

http://msdn.microsoft.com/en-us/library/bb675196.aspx

Upvotes: 0

Alexei Levenkov
Alexei Levenkov

Reputation: 100545

Your "channel" node full name is 'http://purl.org/rss/1.0/':channel. So you need to add both namespaces with any (non-empty) prefixes to your XPathManager and use your prefixes in XPath (completely ignore prefixes in XML - they are not related to your XPath):

private const string RDFXpath = "/rdf:RDF/prefix2:channel";
private const string RDFNamespaceName2 = "prefix2";
var res = doc.XPathSelectElements(RDFXpath, manager);

Specifying "" (empty string) as prefix in namespace manager does not do anything useful for selects. Empty prefix in XPath is always points to default (empty) namespace. This is different from XML where you can override default prefix by using xmlns="new_default_uri" which impacts current and child nodes. This is covered in note to XmlNamespaceManager.AddNamespace.

Upvotes: 1

Related Questions