views:

258

answers:

2

I have the following XML and I have been trying Descendents().Descendents().Descendents to retrieve an element value but I can't get it to work.

I want to return the first value found in the first element of PersonID.

It is a string so I am doing this:

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>
+6  A: 

Actually what you are doing wrong is you are not including Namespaces to your fetch code :

var el = (element.Descendants(XNamespace.Get("PersonInstances") +
"PersonId").FirstOrDefault()).Value;

Use that, It will work.

But let me give you a brief information about namespaces :

<Persons xlmns="something">
 <Person>
  <Name>John</Name>
 </Person>
</Person>

In this example namespace applies to all the descendants but if you want to exclude some of descendants

<Persons xlmns="something">
 <Person>
  <Name>John</Name>
  <LastName xmlns="">Usher</LastName>
 </Person>
</Person>

Now this time LastName will be excluded from this namespace (something)

But if it is hard for you then you can use prefixes to do same thing with less hassle :

<pre:Persons xlmns:pre="something">
 <pre:Person>
  <pre:Name>John</Name>
 </Person>
</Person>

But if you want to include all the descendants into this name space you should use prefix within all descendants as shown the example right above

If you want to exclude some elements from it :

<pre:Persons xlmns:pre="something">
 <Person>
  <pre:Name>John</Name>
 </Person>
</Person>

Then simply remove the prefix, that's it.

You can also do the same thing for attributes :

<pre:Persons xlmns:pre="something">
 <pre:Person>
  <pre:Name pre:Value="Yahoo">John</pre:Name>
 </Person>
</Person>

And if so you need to indicate the namespace within your code every time when you want to get something that has a namespace.

Braveyard
A: 
 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");
 }
Artem K.