How do I get an IXmlNamespaceResolver

前端 未结 3 675
一向
一向 2021-01-11 12:57

I\'m trying to call the XElement.XPathSelectElements() overload that requires an IXmlNamespaceResolver object. Can anyone show me how to get (or make) an IXmlNamespaceResolv

3条回答
  •  感动是毒
    2021-01-11 13:38

    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:

    
    
      
        
          
            105
            0
            
              
                111
                Some Value
                Some description
              
              
                222
                Another Value
                Another description
              
              
                333
                And another Value
                And another description
              
            
          
        
      
    
    

    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 =
                  @"
                        
                            
                            
                                
                                    105
                                    0
                                    
                                        
                                            111
                                            Some Value
                                            Some description
                                        
                                        
                                            222
                                            Another Value
                                            Another description
                                        
                                        
                                            333
                                            And another Value
                                            And another description
                                        
                                    
                                
                            
                            
                        
                        ";
    
                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
    

提交回复
热议问题