Use Linq to Xml with Xml namespaces

前端 未结 4 1774
深忆病人
深忆病人 2020-11-22 15:19

I have this code :

/*string theXml =
@\"

        
相关标签:
4条回答
  • 2020-11-22 15:59

    I have several namespaces listed at the top of an XML document, I don't really care about which elements are from which namespace. I just want to get the elements by their names. I've written this extension method.

        /// <summary>
        /// A list of XElement descendent elements with the supplied local name (ignoring any namespace), or null if the element is not found.
        /// </summary>
        public static IEnumerable<XElement> FindDescendants(this XElement likeThis, string elementName) {
            var result = likeThis.Descendants().Where(ele=>ele.Name.LocalName==elementName);
            return result;
        }
    
    0 讨论(0)
  • 2020-11-22 16:01

    You can pass an XName with a namespace to Descendants() and Element(). When you pass a string to Descendants(), it is implicitly converted to an XName with no namespace.

    To create a XName in a namespace, you create a XNamespace and concatenate it to the element local-name (a string).

    XNamespace ns = "http://myvalue.com";
    XNamespace nsa = "http://schemas.datacontract.org/2004/07/My.Namespace";
    
    var elements = from data in xmlElements.Descendants( ns + "Result")
                       select new
                                  {
                                      TheBool = (bool)data.Element( nsa + "TheBool"),
                                      TheId = (int)data.Element( nsa + "TheId"),
                                  };
    

    There is also a shorthand form for creating a XName with a namespace via implicit conversion from string.

    var elements = from data in xmlElements.Descendants("{http://myvalue.com}Result")
                       select new
                                  {
                                      TheBool = (bool)data.Element("{http://schemas.datacontract.org/2004/07/My.Namespace}TheBool"),
                                      TheId = (int)data.Element("{http://schemas.datacontract.org/2004/07/My.Namespace}TheId"),
                                  };
    

    Alternatively, you could query against XElement.Name.LocalName.

    var elements = from data in xmlElements.Descendants()
                       where data.Name.LocalName == "Result"
    
    0 讨论(0)
  • 2020-11-22 16:09

    LINQ to XML methods like Descendants and Element take an XName as an argument. There is a conversion from string to XName that is happening automatically for you. You can fix this by adding an XNamespace before the strings in your Descendants and Element calls. Watch out because you have 2 different namespaces at work.

    
    string theXml =
                    @"true1";
    
                //string theXml = @"true1";
    
        XDocument xmlElements = XDocument.Parse( theXml );
        XNamespace ns = "http://myvalue.com";
        XNamespace nsa = "http://schemas.datacontract.org/2004/07/My.Namespace";
        var elements = from data in xmlElements.Descendants( ns + "Result" )
              select new
                     {
                         TheBool = (bool) data.Element( nsa + "TheBool" ),
                         TheId = (int) data.Element( nsa + "TheId" ),
                     };
    
        foreach ( var element in elements )
        {
            Console.WriteLine( element.TheBool );
            Console.WriteLine( element.TheId );
        }
    
    

    Notice the use of ns in Descendants and nsa in Elements

    0 讨论(0)
  • 2020-11-22 16:09

    I found the following code to work fine for reading attributes with namespaces in VB.NET:

    MyXElement.Attribute(MyXElement.GetNamespaceOfPrefix("YOUR_NAMESPACE_HERE") + "YOUR_ATTRIB_NAME")
    

    Hope this helps someone down the road.

    0 讨论(0)
提交回复
热议问题