Click here to Skip to main content
15,909,953 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Linq to Xml get elementat
Sorry for the long XML sample below. The XML sample below has two records and each record has three similar Nodes (<datafield tag="500") What I want to accomplish is get the value of the second Node <datafield tag = “5000”>. The fallowing code I gets the value for all three nodes but I want something like get elementat(1). Appreciate your help.
I tried this but it didn’t worked MsgBox(xEle.Elements.ElementAt(1).Value)

Dim xd As XDocument = XDocument.Load("C:\Users\stopete\Desktop\Marc_conv ertxml.xml")
If xd IsNot Nothing Then
Dim datafields = From datafield In xd.Descendants("datafield")
Where (datafield.Attribute("tag").Value = "500")
Select datafield
For Each xEle In datafields
MsgBox(xEle)
Next
End If


XML
<?xml version="1.0"?>
<collection>
    <record>
        <leader>03799cam 2200493Ia 4500</leader>
        <controlfield tag="001">
            648168072
            <subfield code="a">Battle, Stephen L.</subfield>
        </controlfield>
        <controlfield tag="003">SIRSI</controlfield>
        <controlfield tag="005">20110207150903.0</controlfield>
        <controlfield tag="008">100716s2010 caub bm f000 0 eng d</controlfield>
        <controlfield tag="007">cr b|||||a||||</controlfield>
        <datafield tag="035" ind1=" " ind2=" ">
            <subfield code="a">AD#</subfield>
            <subfield code="c">AD#</subfield>
            <subfield code="d">AD#</subfield>
        </datafield>
        <datafield tag="037" ind1=" " ind2=" ">
            <subfield code="a">hey</subfield>
        </datafield>
        <datafield tag="040" ind1=" " ind2=" ">
            <subfield code="a">ADA524509</subfield>
            <subfield code="b">DTI</subfield>
        </datafield>
        <datafield tag="043" ind1=" " ind2=" ">
            <subfield code="a">n-us---</subfield>
        </datafield>
        <datafield tag="049" ind1=" " ind2=" ">
            <subfield code="a">AD#A</subfield>
        </datafield>
        <datafield tag="100" ind1="1" ind2=" ">
            <subfield code="a">Battle, Stephen L.</subfield>
        </datafield>
        <datafield tag="245" ind1="1" ind2="0">
            <subfield code="a">Lessons in legitimacy</subfield>
            <subfield code="h">[electronic resource] :</subfield>
            <subfield code="b">the LTTE end-game of 2007--2009 /</subfield>
            <subfield code="c">Stephen L. Battle.</subfield>
        </datafield>
        <datafield tag="260" ind1=" " ind2=" ">
            <subfield code="a">Monterey, California :</subfield>
            <subfield code="b">Naval Postgraduate School,</subfield>
            <subfield code="c">2010.</subfield>
        </datafield>
        <datafield tag="300" ind1=" " ind2=" ">
            <subfield code="a">xiv, 57 p. :</subfield>
            <subfield code="b">ill. (1 col map) ;</subfield>
            <subfield code="c">28 cm.</subfield>
        </datafield>
        <datafield tag="500">
            <subfield code="a">Thesis Advisor(s): Borer, Douglas A. ; Second Reader: Chatterjee, Anshu.</subfield>
        </datafield>
        <datafield tag="500">
            <subfield code="a">"June 2010."</subfield>
        </datafield>
        <datafield tag="500">
            <subfield code="a">Author(s) subject terms: LTTE, Counter Insurgency, COIN, Sri Lanka, Tamil Eelam, Eelam War IV, SLAF, South Asia.</subfield>
        </datafield>
    </record>
    <record>
        <leader>02919cam 2200493Ia 4500</leader>
        <controlfield tag="001">648167554</controlfield>
        <controlfield tag="003">SIRSI</controlfield>
        <controlfield tag="005">20110207150310.0</controlfield>
        <controlfield tag="008">100716s2010 caua bm f000 0 eng d</controlfield>
        <controlfield tag="007">cr b|||||a||||</controlfield>
        <datafield tag="035" ind1=" " ind2=" ">
            <subfield code="a">AD#</subfield>
            <subfield code="c">AD#</subfield>
            <subfield code="d">AD#</subfield>
        </datafield>
        <datafield tag="037" ind1=" " ind2=" ">
            <subfield code="a">hey</subfield>
        </datafield>
        <datafield tag="040" ind1=" " ind2=" ">
            <subfield code="a">ADA524541</subfield>
            <subfield code="b">DTI</subfield>
        </datafield>
        <datafield tag="043" ind1=" " ind2=" ">
            <subfield code="a">n-us---</subfield>
        </datafield>
        <datafield tag="049" ind1=" " ind2=" ">
            <subfield code="a">AD#A</subfield>
        </datafield>
        <datafield tag="100" ind1="1" ind2=" ">
            <subfield code="a">Battaglia, Neal F.</subfield>
        </datafield>
        <datafield tag="245" ind1="1" ind2="0">
            <subfield code="a">Utility of satellite LIDAR waveform data in shallow water</subfield>
            <subfield code="h">[electronic resource] /</subfield>
            <subfield code="c">Neal F. Battaglia.</subfield>
        </datafield>
        <datafield tag="260" ind1=" " ind2=" ">
            <subfield code="a">Monterey, California :</subfield>
            <subfield code="b">Naval Postgraduate School,</subfield>
            <subfield code="c">2010.</subfield>
        </datafield>
        <datafield tag="300" ind1=" " ind2=" ">
            <subfield code="a">xvi, 67 p. :</subfield>
            <subfield code="b">ill. (some col.) ;</subfield>
            <subfield code="c">28 cm.</subfield>
        </datafield>
        <datafield tag="500">
            <subfield code="a">Thesis Advisor(s): Olsen, Richard C. ; Second Reader: Trask, David M.</subfield>
        </datafield>
        <datafield tag="500">
            <subfield code="a">"June 2010."</subfield>
        </datafield>
        <datafield tag="500">"
            <subfield code="a">Author(s) subject terms: LIDAR Waveforms, Underwater LIDAR signature, Spaceborne LIDAR.</subfield>
        </datafield>
    </record>
</collection>
Posted
Updated 15-Apr-11 6:45am
v3

You could Skip the first element if you want the second one specifically like this:

<code>
 Dim datafields = (From datafield In xd.Descendants("datafield")    Where (datafield.Attribute("tag").Value = "500")    Select datafield).Skip(1).First()
</code>


Additionally you could skip as many items as you like, not just the first one.
Hope this helped :) Good luck
 
Share this answer
 
Comments
stopete82 15-Apr-11 13:36pm    
Thanks for the quick response. With your help I think I am in the right track. However; the sample you send I get the right output for the first record but then it doesn't go to next record. Do you know what I need to add to go to the next record?

Code:

Dim xd As XDocument = XDocument.Load("C:\Users\stopete\Desktop\Marc_convertxml.xml")
If xd IsNot Nothing Then

Dim datafields = (From datafield In xd.Descendants("datafield")
Where (datafield.Attribute("tag").Value = "500")
Select datafield).Skip(0).First()


For Each xEle In datafields.Elements

MsgBox(xEle)

Next

End If

Ouput:

Thesis Advisor(s): Borer, Douglas A. ; Second Reader: Chatterjee, Anshu.



Disire output:

First record
Thesis Advisor(s): Borer, Douglas A. ; Second Reader: Chatterjee, Anshu.

Second record
Thesis Advisor(s): Olsen, Richard C. ; Second Reader: Trask, David M.


Thanks for all your help.
mario_silent 15-Apr-11 14:19pm    
Ok here you go. First we get the XElements of the records, and loop through them to select the tag with attribute == 500. This should display in your test xml both records:
<pre>

var records = (from datafields in xd.Descendants("record") select datafields);
foreach (XElement e in records)
{
var data = (from datafield in e.Descendants("datafield")
where (datafield.Attribute("tag").Value == "500")
select datafield).Skip(0).First();
Console.WriteLine(data.Value);
}

</pre>

SOrry if it's in c# but it shouldn't be a problem to translate to VB, just a few tweaks :) Hope this helps
stopete82 15-Apr-11 17:43pm    
Sorry, for some reason I didn't see your code. However, I converted the code to VB.net but I get a syntax error Variable 'e' hides a variable in an enclosing block. Maybe somebody can see what I am missing in code. Apprciate your help.

Code:

Dim xd As XDocument = XDocument.Load("C:\Users\stopete\Desktop\Marc_convertxml.xml")

Dim records = (From datafields In xd.Descendants("record")
Select datafields)


For Each e As XElement In records
Dim data = (From datafield In e.Descendants("datafield") Where (datafield.Attribute("tag").Value = "500")
Select datafield).Skip(0).First()
MsgBox(data.Value)
Next

mario_silent 15-Apr-11 17:47pm    
I think you can ommit the e as XElement and just leave for each e In records like you had done previously
stopete82 15-Apr-11 14:34pm    
Thanks for the reply Skip(0) works it gives me the right result for the first record. However; the problem now is that it stops at first record, do you know what I need to add so it will traverse the whole xml document.
You can also you an XPath expression in LINQ.
Here is how it can be done :


VB
Dim datafields = (From datafield in xd.XPathSelectElement("//datafield[@tag='500' and position()=2]") _
select datafield)


It will return a single element of Type XElement.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900