Возвращаем значение элемента глубоко внутри XDocument
-
05-07-2019 - |
Вопрос
У меня есть следующий XML, и я пытался Descendents (). Descendents (). Потомки, чтобы получить значение элемента, но я не могу заставить его работать.
Я хочу вернуть первое значение, найденное в первом элементе PersonID.
Это строка, поэтому я делаю это:
XDocument XDoc = XDocument.Parse(XmlString);
<Root>
<Code>200001</Code>
<MsgType>106</MsgType>
<PersonData>
<MSG>
<NewDataSet xmlns="PersonInstances">
<PersonInstances>
<PersonInstanceId>1</PersonInstanceId>
<PersonId>400</PersonId>
<Status>210005</Status>
<DateChanged>2009-10-20T11:53:00+01:00</DateChanged>
</PersonInstances>
<PersonInstances>
<PersonInstanceId>2</PersonInstanceId>
<PersonId>400</PersonId>
<Status>210005</Status>
<DateChanged>2009-10-20T12:13:00+01:00</DateChanged>
</PersonInstances>
<PersonInstances>
<PersonInstanceId>3</PersonInstanceId>
<PersonId>400</PersonId>
<Status>210005</Status>
<DateChanged>2009-10-20T15:28:00+01:00</DateChanged>
</PersonInstances>
<PersonInstances>
<PersonInstanceId>4</PersonInstanceId>
<PersonId>400</PersonId>
<Status>210005</Status>
<DateChanged>2009-10-20T15:32:00+01:00</DateChanged>
</PersonInstances>
<PersonInstances>
<PersonInstanceId>5</PersonInstanceId>
<PersonId>400</PersonId>
<Status>210005</Status>
<DateChanged>2009-10-21T10:49:00+01:00</DateChanged>
</PersonInstances>
<PersonInstances>
<PersonInstanceId>6</PersonInstanceId>
<PersonId>400</PersonId>
<Status>210005</Status>
<DateChanged>2009-10-21T17:15:00+01:00</DateChanged>
</PersonInstances>
<PersonInstances>
<PersonInstanceId>7</PersonInstanceId>
<PersonId>400</PersonId>
<Status>210005</Status>
<DateChanged>2009-10-22T10:06:00+01:00</DateChanged>
</PersonInstances>
<PersonInstances>
<PersonInstanceId>8</PersonInstanceId>
<PersonId>400</PersonId>
<Status>210005</Status>
<DateChanged>2009-10-22T16:01:00+01:00</DateChanged>
</PersonInstances>
</NewDataSet></MSG></PersonData></Root>
Решение
На самом деле, что вы делаете неправильно, вы не включаете пространства имен в код извлечения:
var el = (element.Descendants(XNamespace.Get("PersonInstances") +
"PersonId").FirstOrDefault()).Value;
Используйте это, это будет работать.
Но позвольте мне дать вам краткую информацию о пространствах имен:
<Persons xlmns="something">
<Person>
<Name>John</Name>
</Person>
</Person>
В этом примере пространство имен применяется ко всем потомкам, но если вы хотите исключить некоторых из потомков
<Persons xlmns="something">
<Person>
<Name>John</Name>
<LastName xmlns="">Usher</LastName>
</Person>
</Person>
Теперь на этот раз LastName будет исключен из этого пространства имен (что-то)
Но если вам трудно, вы можете использовать префиксы, чтобы делать то же самое с меньшими хлопотами:
<pre:Persons xlmns:pre="something">
<pre:Person>
<pre:Name>John</Name>
</Person>
</Person>
Но если вы хотите включить всех потомков в это пространство имен, вы должны использовать префикс во всех потомках, как показано в примере выше
Если вы хотите исключить некоторые элементы из него:
<pre:Persons xlmns:pre="something">
<Person>
<pre:Name>John</Name>
</Person>
</Person>
Затем просто удалите префикс, вот и все.
Вы также можете сделать то же самое для атрибутов:
<pre:Persons xlmns:pre="something">
<pre:Person>
<pre:Name pre:Value="Yahoo">John</pre:Name>
</Person>
</Person>
И если это так, вам нужно указывать пространство имен в вашем коде каждый раз, когда вы хотите получить что-то, имеющее пространство имен.
Другие советы
XDocument XDoc = XDocument.Parse(xfile);
XNamespace ns = "PersonInstances";
if (XDoc.Root.Descendants(ns + "PersonId").Any())
{
Console.Write(XDoc.Root.Descendants(ns + "PersonId").First().Value);
}
else
{
Console.Write("Fail");
}