I have following part of xml file.
<UN N="@U1">
<DT N="24/06/2011">
<PN N="@P1">
<TM N="02:24:11">
<JB T="GP">
<A>notepad</A>
<Z>Notepad</Z>
<N>Untitled - Notepad</N>
<J>1;0;1;1;0;0</J>
<C>0.00500;0.09500;0.03500</C>
<S>1;0;1;1</S>
<P>0;0</P>
<F>0</F>
</JB>
</TM>
</PN>
</DT>
<DT N="23/06/2011">
<PN N="@P1">
<TM N="02:38:49">
<JB T="PAGP">
<A>notepad</A>
<Z>Notepad</Z>
<N>Untitled - Notepad</N>
<J>1;1;1;1;0;1</J>
<C>0.00500;0.09500;0.03500</C>
<S>1;1;0;0</S>
<P>1;1</P>
<F>0</F>
</JB>
</TM>
</PN>
</DT>
.....
.....
</UN>
I need to get the last node where PN N=@P1.
Sample query will be appreciated.
Thanks in advance.
The XPath operation:
"/UN/DT[PN/@N='@p1'][last()]"
will return the last DT node for which PN=@p1
.
The last()
XPath function can be used to find the last of a node set. So the last <PN>
node with attribyte N
having a value @P1
would be:
//PN[@N='@P1'][position() = last()]
The .NET code will depend on which XML API you're using: XmlDocument
, XPathDocument
or LINQ to XML (XDocument
). (The approach with XmlReader
would be to load into one of the three and then use that.)
Edit (based on comment) To return the <F>
descendant of the last <PN>
with attribute as above, where xDoc
is an instance of XmlDocument
:
var foundNode = xDoc.SelectSingleNode("//PN[@N='@P1'][position() = last()]/TM/JB/F");
Edit #2 (based on another comment): To return the last <PN>
where each <DT>
can contain multiple <DT>
elements1 across all the <DT>
elements.
Testing this with some better sample XML (see below), using XmlElement.SelectNodes
and then iterating over the returned node set showed that the right node was being found, it just wasn't the first and therefore not returned by SelectSingleNode
. This is the clue: the last()
predicate was being applied within each //PN[@N='@P1']
matching. A quick change of precedence was all that was needed:
(//PN[@N='@P1'])[last()]
1 For future reference, if multiple elements are possible, then show at least two in the sample, otherwise readers will assume only singular instances. Also strip out all nodes (like children) not needed:
The sample XML I used for testing (added x attributes to make it easy to identify the element selected while testing):
<UN N='@U1'>
<DT N='24/06/2011'>
<PN N='@P1' x='#1'/>
<PN N='@P1' x='#2'/>
<PN N='@P2' x='#3'/>
</DT>
<DT N='24/06/2011'>
<PN N='@P1' x='#4'/>
<PN N='@P1' x='#5'/>
<PN N='@P2' x='#6'/>
</DT>
<DT N='24/06/2011'>
<PN N='@P3' x='#7'/>
<PN N='@P4' x='#8'/>
<PN N='@P5' x='#9'/>
</DT>
</UN>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With