How do I get an IXmlNamespaceResolver

爷,独闯天下 提交于 2019-12-04 00:06:29

问题


I'm trying to call the XElement.XPathSelectElements() overload that requires an IXmlNamespaceResolver object. Can anyone show me how to get (or make) an IXmlNamespaceResolver? I have a list of the namespaces I want to use in my query


回答1:


You can use an XmlNamespaceManager that implements that interface

Use the constructor which takes an XmlNameTable, passing into it an instance of System.Xml.NameTable via new NameTable(). You can then call AddNamespace function to add namespaces:

var nsMgr = new XmlNamespaceManager(new NameTable());
nsMgr.AddNamespace("ex", "urn:example.org");
nsMgr.AddNamespace("t", "urn:test.org");
doc.XPathSelectElements("/ex:path/ex:to/t:element", nsMgr);



回答2:


Use new XmlNamespaceManager(new NameTable()).

For example, if you have an XML document that uses namespaces like

var xDoc = XDocument.Parse(@"<m:Student xmlns:m='http://www.ludlowcloud.com/Math'>
    <m:Grade>98</m:Grade>
    <m:Grade>96</m:Grade>
</m:Student>");

then you can get the Grade nodes by doing

var namespaceResolver = new XmlNamespaceManager(new NameTable());
namespaceResolver.AddNamespace("math", "http://www.ludlowcloud.com/Math");
var grades = xDoc.XPathSelectElements("//math:Student/math:Grade", namespaceResolver);



回答3:


I found this post while searching on how to use the overload of [XPathSelectElements()] to process a SOAP response so, I will post my answer in case it is usefull for others who have a document with several namespace definitions. In my case I have a document like this:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <queryResponse xmlns="http://SomeUrl.com/SomeSection">
      <response>
        <theOperationId>105</theOperationId>
        <theGeneraltheDetailsCode>0</theGeneraltheDetailsCode>
        <theDetails>
          <aDetail>
            <aDetailId>111</aDetailId>
            <theValue>Some Value</theValue>
            <theDescription>Some description</theDescription>
          </aDetail>
          <aDetail>
            <aDetailId>222</aDetailId>
            <theValue>Another Value</theValue>
            <theDescription>Another description</theDescription>
          </aDetail>
          <aDetail>
            <aDetailId>333</aDetailId>
            <theValue>And another Value</theValue>
            <theDescription>And another description</theDescription>
          </aDetail>
        </theDetails>
      </response>
    </queryResponse>
  </soap:Body>
</soap:Envelope>

To create the [XDocument]:

var theDocumentXDoc = XDocument.Parse( theDocumentContent );

To create the [XmlNamespaceManager], I use:

var theNamespaceIndicator = new XmlNamespaceManager( new NameTable() );
theNamespaceIndicator.AddNamespace( "theSoapNS", "http://www.w3.org/2003/05/soap-envelope" );
theNamespaceIndicator.AddNamespace( "noSuffNS" , "http://SomeUrl.com/SomeSection" );

The names I use for the prefixes ( "theSoapNS" and "noSuffNS" ) are arbitrary. Use a name that is convenient for a readable code.

To select the [Envelope] element, I use:

var theEnvelope = theDocumentXDoc.XPathSelectElement( "//theSoapNS:Envelope", theNamespaceIndicator );

To select the [queryResponse] element:

var theQueryResponse = theDocumentXDoc.XPathSelectElement( "//theSoapNS:Envelope/theSoapNS:Body/noSuffNS:queryResponse", theNamespaceIndicator );

To select all details in [theDetails]:

var theDetails = theDocumentXDoc.XPathSelectElement( "//theSoapNS:Envelope/theSoapNS:Body/noSuffNS:queryResponse/noSuffNS:response/noSuffNS:theDetails", theNamespaceIndicator );

Here is an example program (C#6) using the selections:

//The usings you need:
using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

namespace ProcessXmlCons
{
    class Inicial
    {
        static void Main(string[] args)
        {
            new Inicial().Tests();
        }

        private void Tests()
        {
            Test01();
        }

        private void Test01()
        {
            var theDocumentContent =
              @"<?xml version=""1.0"" encoding=""utf-8""?>
                    <soap:Envelope xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
                        <soap:Body>
                        <queryResponse xmlns=""http://SomeUrl.com/SomeSection"">
                            <response>
                                <theOperationId>105</theOperationId>
                                <theGeneraltheDetailsCode>0</theGeneraltheDetailsCode>
                                <theDetails>
                                    <aDetail>
                                        <aDetailId>111</aDetailId>
                                        <theValue>Some Value</theValue>
                                        <theDescription>Some description</theDescription>
                                    </aDetail>
                                    <aDetail>
                                        <aDetailId>222</aDetailId>
                                        <theValue>Another Value</theValue>
                                        <theDescription>Another description</theDescription>
                                    </aDetail>
                                    <aDetail>
                                        <aDetailId>333</aDetailId>
                                        <theValue>And another Value</theValue>
                                        <theDescription>And another description</theDescription>
                                    </aDetail>
                                </theDetails>
                            </response>
                        </queryResponse>
                        </soap:Body>
                    </soap:Envelope>
                    ";

            var theDocumentXDoc = XDocument.Parse(theDocumentContent);
            var theNamespaceIndicator = new XmlNamespaceManager(new NameTable());
            theNamespaceIndicator.AddNamespace("theSoapNS", "http://www.w3.org/2003/05/soap-envelope");
            theNamespaceIndicator.AddNamespace("noSuffNS", "http://SomeUrl.com/SomeSection");

            var theEnvelope = theDocumentXDoc.XPathSelectElement("//theSoapNS:Envelope", theNamespaceIndicator);
            Console.WriteLine($"The envelope: {theEnvelope?.ToString()} ");

            var theEnvelopeNotFound = theDocumentXDoc.XPathSelectElement("//Envelope", theNamespaceIndicator);
            Console.WriteLine("".PadRight(120, '_')); //Visual divider
            Console.WriteLine($"The other envelope: \r\n {theEnvelopeNotFound?.ToString()} ");

            var theQueryResponse = theDocumentXDoc.XPathSelectElement("//theSoapNS:Envelope/theSoapNS:Body/noSuffNS:queryResponse", theNamespaceIndicator);
            Console.WriteLine("".PadRight(120, '_')); //Visual divider
            Console.WriteLine($"The query response: \r\n {theQueryResponse?.ToString()} ");

            var theDetails = theDocumentXDoc.XPathSelectElement("//theSoapNS:Envelope/theSoapNS:Body/noSuffNS:queryResponse/noSuffNS:response/noSuffNS:theDetails", theNamespaceIndicator);
            Console.WriteLine("".PadRight(120, '_')); //Visual divider
            Console.WriteLine($"The details: \r\n {theDetails?.ToString()} ");
            Console.WriteLine("".PadRight(120, '_')); //Visual divider

            foreach (var currentDetail in theDetails.Descendants().Where(elementToFilter => elementToFilter.Name.LocalName != "aDetail"))
            {
                Console.WriteLine($"{currentDetail.Name.LocalName}: {currentDetail.Value}");
            }

            //Not optimal. Just to show XPath select within another selection:
            Console.WriteLine("".PadRight(120, '_')); //Visual divider
            Console.WriteLine("Values only:");
            foreach (var currentDetail in theDetails.Descendants())
            {
                var onlyTheValueElement = currentDetail.XPathSelectElement("noSuffNS:theValue", theNamespaceIndicator);
                if (onlyTheValueElement != null)
                {
                    Console.WriteLine($"--> {onlyTheValueElement.Value}");
                }
            }
        }

    } //class Inicial
} //namespace ProcessXmlCons


来源:https://stackoverflow.com/questions/14712718/how-do-i-get-an-ixmlnamespaceresolver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!