Get nodes from xml files

前端 未结 3 498
失恋的感觉
失恋的感觉 2020-12-06 13:23

How to parse the xml file?


 
<         


        
3条回答
  •  -上瘾入骨i
    2020-12-06 13:52

    The problem is that the sitemapindex element defines a default namespace. You need to specify the namespace when you select the nodes, otherwise it will not find them. For instance:

    XmlDocument xml = new XmlDocument();
    xml.Load("sitemap.xml");
    XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
    manager.AddNamespace("s", "http://www.sitemaps.org/schemas/sitemap/0.9");
    XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);
    

    Normally speaking, when using the XmlNameSpaceManager, you could leave the prefix as an empty string to specify that you want that namespace to be the default namespace. So you would think you'd be able to do something like this:

    // WON'T WORK
    XmlDocument xml = new XmlDocument();
    xml.Load("sitemap.xml");
    XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
    manager.AddNamespace("", "http://www.sitemaps.org/schemas/sitemap/0.9"); //Empty prefix
    XmlNodeList xnList = xml.SelectNodes("/sitemapindex/sitemap", manager); //No prefixes in XPath
    

    However, if you try that code, you'll find that it won't find any matching nodes. The reason for this is that in XPath 1.0 (which is what XmlDocument implements), when no namespace is provided, it always uses the null namespace, not the default namespace. So, it doesn't matter if you specify a default namespace in the XmlNamespaceManager, it's not going to be used by XPath, anyway. To quote the relevant paragraph from the Official XPath Specification:

    A QName in the node test is expanded into an expanded-name using the namespace declarations from the expression context. This is the same way expansion is done for element type names in start and end-tags except that the default namespace declared with xmlns is not used: if the QName does not have a prefix, then the namespace URI is null (this is the same way attribute names are expanded). It is an error if the QName has a prefix for which there is no namespace declaration in the expression context.

    Therefore, when the elements you are reading belong to a namespace, you can't avoid putting the namespace prefix in your XPath statements. However, if you don't want to bother putting the namespace URI in your code, you can just use the XmlDocument object to return the URI of the root element, which in this case, is what you want. For instance:

    XmlDocument xml = new XmlDocument();
    xml.Load("sitemap.xml");
    XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
    manager.AddNamespace("s", xml.DocumentElement.NamespaceURI); //Using xml's properties instead of hard-coded URI
    XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);
    

提交回复
热议问题