Use Linq para Xml con espacios de nombres Xml

Tengo este código:

/*string theXml = @"true1";*/ string theXml = @"true1"; XDocument xmlElements = XDocument.Parse(theXml); var elements = from data in xmlElements.Descendants("Result") select new { TheBool = (bool)data.Element("TheBool"), TheId = (int)data.Element("TheId"), }; foreach (var element in elements) { Console.WriteLine(element.TheBool); Console.WriteLine(element.TheId); } 

Cuando uso el primer valor para el XML, el resultado es nulo, mientras que con el segundo, tengo buenos valores …

¿Cómo usar Linq en Xml con valores xmlns?

Los métodos LINQ a XML como Descendants y Element toman un XName como argumento. Hay una conversión de string a XName que está sucediendo automáticamente para usted. Puede solucionar esto agregando un XNamespace antes de las cadenas en sus llamadas a Descendants y Element . Ten cuidado porque tienes 2 espacios de nombres diferentes en el trabajo.

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 ); }
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 ); } 

Observe el uso de ns en Descendants y nsa en Elements

Puede pasar un XName con un espacio de nombre a Descendientes () y Elemento () . Cuando pasa una cadena a Descendants (), se convierte implícitamente en un XName sin espacio de nombres.

Para crear un XName en un espacio de nombres, cree un XNamespace y conéctelo al elemento local-name (una cadena).

 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"), }; 

También hay una forma abreviada para crear un XName con un espacio de nombres a través de la conversión implícita de la cadena.

 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"), }; 

Alternativamente, puede consultar contra XElement. Name.LocalName .

 var elements = from data in xmlElements.Descendants() where data.Name.LocalName == "Result" 

Tengo varios espacios de nombres enumerados en la parte superior de un documento XML, realmente no me importa qué elementos son de qué espacio de nombres. Solo quiero obtener los elementos por sus nombres. He escrito este método de extensión.

  ///  /// A list of XElement descendent elements with the supplied local name (ignoring any namespace), or null if the element is not found. ///  public static IEnumerable FindDescendants(this XElement likeThis, string elementName) { var result = likeThis.Descendants().Where(ele=>ele.Name.LocalName==elementName); return result; } 

Encontré el siguiente código que funciona bien para leer atributos con espacios de nombres en VB.NET:

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

Espero que esto ayude a alguien en el camino.