Сортировка XML с использованием XPath в .Net - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь получить самую последнюю «окончательную» запись из списка, например:

<StatusRecords>
<Status>
<Name>final</Name>
<Date>1/1/2006</Date>
</Status>
<Status>
<Name>final</Name>
<Date>1/1/2010</Date>
</Status>
<Status>
<Name>interim</Name>
<Date>1/1/2005</Date>
</Status>
</StatusRecords>

Предполагается, что данные имеют только одну «окончательную» запись статуса, и я написалкод, чтобы просто найти эту одну запись.Но мы обнаружили, что фактические данные заполнены несколькими «финальными», как это.Поэтому мне нужно получить тот, у которого самая высокая дата.

Я вижу, что это возможно при использовании Xpath , как я уже выполняю синтаксический анализ, но я не понимаю, как перевестиэто в код VB.Net.У кого-нибудь есть фрагмент?

Ответы [ 3 ]

0 голосов
/ 11 октября 2018

Если он не имеет через XSL, вы можете использовать LINQ-to-XML для получения данных, например:

Module Module1

    Sub Main()
        Dim x = <StatusRecords>
                    <Status>
                        <Name>final</Name>
                        <Date>1/1/2006</Date>
                    </Status>
                    <Status>
                        <Name>final</Name>
                        <Date>1/1/2010</Date>
                    </Status>
                    <Status>
                        <Name>interim</Name>
                        <Date>1/1/2005</Date>
                    </Status>
                </StatusRecords>

        Dim ci = Globalization.CultureInfo.GetCultureInfo("en-US")

        Dim y = x...<Status>.<Date>.Max(Function(d) DateTime.Parse(d.Value, ci))

        Dim z = x...<Status>.First(Function(s) DateTime.Parse(s.<Date>.Value, ci) = y)

        Console.WriteLine("Latest date: " & y.ToString("yyyy-MM-dd"))
        Console.WriteLine(z)

        Console.ReadLine()

    End Sub

End Module

, который выводит:

Latest date: 2010-01-01
<Status>
  <Name>final</Name>
  <Date>1/1/2010</Date>
</Status>
0 голосов
/ 11 октября 2018

Комментарий TonyE выше, в конечном итоге, стал ключом к решению этой проблемы.Проблема в том, что вам нужно преобразовать дату в число, а затем использовать максимальное значение для этого числа.Результат грязный, но, похоже, работает:

/StatusRecords/Status[number(concat(substring(Date, 1, 4),substring(Date, 6,2),substring(Date, 9, 2),substring(Date, 12, 2),substring(Date, 15, 2),substring(Date, 18, 2)))=max(/StatusRecords/Status/number(concat(substring(Date, 1, 4),substring(Date, 6,2),substring(Date, 9, 2),substring(Date, 12, 2),substring(Date, 15, 2),substring(Date, 18, 2))))]

Я подозреваю, что существует более простой и компактный формат, но работа - это особенность.Спасибо, Тони!

ОБНОВЛЕНИЕ: оказывается, нужна была и часть hms.

0 голосов
/ 11 октября 2018

Вот один из способов сделать это

    Dim myxml As String = "<StatusRecords><Status><Name>final</Name><Date>1/1/2006</Date></Status><Status><Name>final</Name><Date>1/1/2010</Date></Status><Status><Name>interim</Name><Date>1/1/2005</Date></Status></StatusRecords>"
    Dim xp As XPathDocument = New XPathDocument(New StringReader(myxml.ToString))
    Dim xn As XPathNavigator = xp.CreateNavigator
    Dim xi As XPathNodeIterator = xn.Select("//StatusRecords/Status")
    Dim thedate As Date = "1/1/1900" 
    Dim loopdate As Date
    Dim maxfinal As String = "?"
    Do While xi.MoveNext
        loopdate = CDate(xi.Current.SelectSingleNode("Date").InnerXml)
        If loopdate > thedate Then
            thedate = loopdate
            maxfinal = xi.Current.SelectSingleNode("Name").InnerXml
        End If
    Loop
    Response.Write(maxfinal & ":" & thedate.ToShortDateString)

Вывод

final:1/1/2010
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...