Использование Linq to Xml с пространствами имен Xml
У меня есть этот код :
/*string theXml =
@"<Response xmlns=""http://myvalue.com""><Result xmlns:a=""http://schemas.datacontract.org/2004/07/My.Namespace"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""><a:TheBool>true</a:TheBool><a:TheId>1</a:TheId></Result></Response>";*/
string theXml = @"<Response><Result><TheBool>true</TheBool><TheId>1</TheId></Result></Response>";
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);
}
когда я использую первое значение для theXml, результат равен нулю, тогда как со вторым у меня есть хорошие значения ...
Как использовать Linq to Xml со значениями xmlns ?
4 ответа:
LINQ to XML методы, такие как
Descendants
иElement
взятьXName
в качестве аргумента. Существует преобразование изstring
доXName
что происходит автоматически для вас. Вы можете исправить это, добавивXNamespace
до строкиDescendants
иElement
звонки. Будьте осторожны, потому что у вас есть 2 разных пространства имен на работе.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 ); }
обратите внимание на использование ns в
Descendants
и АНБ вElements
вы можете передать XName С пространством имен для потомки() и Element (). Когда вы передаете строку потомкам (), она неявно преобразуется в XName без пространства имен.
чтобы создать XName в пространстве имен, Необходимо создать XNamespace и связать его с элементом local-name (строка).
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"), };
существует также сокращенная форма для создания XName с пространством имен с помощью неявного преобразования из строка.
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"), };
кроме того, вы можете запросить XElement.имя.LocalName.
var elements = from data in xmlElements.Descendants() where data.Name.LocalName == "Result"
У меня есть несколько пространств имен, перечисленных в верхней части XML-документа, я действительно не забочусь о том, какие элементы из какого пространства имен. Я просто хочу получить элементы по их именам. Я написал этот метод расширения.
/// <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; }