Restituisce il valore dell'elemento in profondità all'interno di XDocument
-
05-07-2019 - |
Domanda
Ho il seguente XML e ho provato Descendents (). Descendents (). Discendenti per recuperare un valore di elemento ma non riesco a farlo funzionare.
Voglio restituire il primo valore trovato nel primo elemento di PersonID.
È una stringa, quindi lo sto facendo:
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>
Soluzione
In realtà ciò che stai facendo di sbagliato è che non stai includendo Namespace nel tuo codice di recupero:
var el = (element.Descendants(XNamespace.Get("PersonInstances") +
"PersonId").FirstOrDefault()).Value;
Usalo, Funzionerà.
Ma lascia che ti dia una breve informazione sugli spazi dei nomi:
<Persons xlmns="something">
<Person>
<Name>John</Name>
</Person>
</Person>
In questo esempio lo spazio dei nomi si applica a tutti i discendenti ma se si desidera escludere alcuni dei discendenti
<Persons xlmns="something">
<Person>
<Name>John</Name>
<LastName xmlns="">Usher</LastName>
</Person>
</Person>
Ora questa volta LastName sarà escluso da questo spazio dei nomi (qualcosa)
Ma se è difficile per te, puoi usare i prefissi per fare la stessa cosa con meno problemi:
<pre:Persons xlmns:pre="something">
<pre:Person>
<pre:Name>John</Name>
</Person>
</Person>
Ma se vuoi includere tutti i discendenti in questo spazio dei nomi, dovresti usare il prefisso all'interno di tutti i discendenti come mostrato nell'esempio sopra
Se vuoi escludere alcuni elementi da esso:
<pre:Persons xlmns:pre="something">
<Person>
<pre:Name>John</Name>
</Person>
</Person>
Quindi rimuovi semplicemente il prefisso, tutto qui.
Puoi anche fare la stessa cosa per gli attributi:
<pre:Persons xlmns:pre="something">
<pre:Person>
<pre:Name pre:Value="Yahoo">John</pre:Name>
</Person>
</Person>
E in tal caso devi indicare lo spazio dei nomi nel tuo codice ogni volta che vuoi ottenere qualcosa che abbia uno spazio dei nomi.
Altri suggerimenti
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");
}