2

I have next xml:

<Histories>
    <History>
        <Date>20.06.2010</Date>
        <FileName>4.txt</FileName>
    </History>
    <History>
        <Date>05.06.2012</Date>
        <FileName>2.txt</FileName>
    </History>
    <History>
        <Date>18.12.1999</Date>
        <FileName>3.txt</FileName>
    </History>
</Histories>

I need to get last node by date (set XPath witch return date). How can I do? Example: 2.txt

Thanks

2
  • >/Histories/History[ not( (preceding-sibling::History | following-sibling::History)/Date > Date ) ] not work for my formate date Commented Mar 28, 2012 at 5:38
  • Indeed. It is not possible to do this with your date-format in just XPath 1.0. Alternatives offered are: XPath 2.0, LINQ to XML, XSLT and XQuery. Commented Mar 28, 2012 at 5:47

4 Answers 4

3

In XPath 2.0 you can do it like this:

/Histories/History[
    concat(substring(Date,7),substring(Date,4,2),substring(Date,1,2)) =
    max(/Histories/History/concat(substring(Date,7),substring(Date,4,2),
        substring(Date,1,2)))
]

The first part (concat(...)) converts the date into YYYYMMDD format to allow sorting. It then compares it to the maximum such value in the file.

This would not be possible in XPath 1.x, since there are no max() function, nor can you call functions at the end of a path (/Histories/History/concat(...)).

Natively, .NET does not support XPath 2.0, but there are libraries that add this.

Sign up to request clarification or add additional context in comments.

1 Comment

+1. If the OP had useful date formats, this would be pretty simple in XPath 1.0. I've added an "if only"-solution.
2

If you had proper dates in your XML (yyyyddmm instead of dd.mm.yyyy), this XPath 1.0 would work:

/Histories/History[
  not(
    (preceding-sibling::History | following-sibling::History)/Date > Date
  )
]

Since you have your dates the wrong way, XPath 1.0 cannot do this.

Comments

2

This is not specific to WPF.

Did you try using XQuery or XLinq for this?

        var element = XElement.Parse(<yourXml>);
        var lastDateHistoryNode
              = element.XPathSelectElements("//History").OrderByDescending(
                   e => DateTime.ParseExact(
                          e.Element("Date").Value, "dd.MM.yyyy", null)).First();
        var lastDateFileName = lastDateHistoryNode.Element("FileName").Value;

Comments

0

XPath on its own won't allow you to select from an ordered list. If you can use XSLT first (in particular <xsl:sort>) to obtain a sorted node-set, then selecting the first or last element is trivial (nodeset[1] or nodeset[last()].

To have the dates sorted chronologically it's also wise to convert them to ISO first (YYYY-MM-DD) as then the string order coincides with the chronological order.

1 Comment

XPath does not let you select from an ordered list, but there are ways to get the minimum/maximum value from a node set - as long as the values sort naturally (which dd.mm.yyyy does not do, unfortunately).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.