#linq-to-xml
Вопрос:
Давайте предположим, что у нас есть этот xml:
<?xml version="1.0" encoding="UTF-8"?>
<tns:RegistryResponse status="urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Failure"
xmlns:tns="urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0"
xmlns:rim="urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0">
<tns:RegistryErrorList highestSeverity="">
<tns:RegistryError codeContext="XDSInvalidRequest - DcoumentId is not unique."
errorCode="XDSInvalidRequest"
severity="urn:oasis:names:tc:ebxml-regrep:ErrorSeverityType:Error"/>
</tns:RegistryErrorList>
</tns:RegistryResponse>
Чтобы получить элемент RegistryErrorList, мы можем сделать
XDocument doc = XDocument.Load(<path to xml file>);
XNamespace ns = "urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0";
XElement errorList = doc.Root.Elements( ns "RegistryErrorList").SingleOrDefault();
но не так, как сейчас
XElement errorList = doc.Root.Elements("RegistryErrorList").SingleOrDefault();
Есть ли способ выполнить запрос без пространства имен элемента. В принципе, есть ли что-то концептуально
похожее на использование local-name() в XPath (т. Е. //*[local-name()=’RegistryErrorList’])
Ответ №1:
var q = from x in doc.Root.Elements()
where x.Name.LocalName=="RegistryErrorList"
select x;
var errorList = q.SingleOrDefault();
Ответ №2:
В синтаксисе «метода» запрос будет выглядеть следующим образом:
XElement errorList = doc.Root.Elements().Where(o => o.Name.LocalName == "RegistryErrorList").SingleOrDefault();
Ответ №3:
Следующее расширение вернет коллекцию совпадающих элементов с любого уровня XDocument (или любого XContainer).
public static IEnumerable<XElement> GetElements(this XContainer doc, string elementName)
{
return doc.Descendants().Where(p => p.Name.LocalName == elementName);
}
Ваш код теперь будет выглядеть следующим образом:
var errorList = doc.GetElements("RegistryErrorList").SingleOrDefault();