Синтаксис запроса XPATH в коде VBA для выбора минимального значения даты - PullRequest
1 голос
/ 26 февраля 2020

Я использую Microsoft XML, v3.0 в Word VBA (Word 2016, VBA 7.1), для извлечения данных из XML, возвращаемых из базы данных SQL Server 2008 с запросом FOR XML.

Я хочу извлечь указанную c дату, поэтому я создаю запрос XPath:

xpath = "//XMLPKG/CASE/EVENT[OCCURRED=0][@EVENTNO='23']/DUEDATE"

, затем запускаю SelectNodes:

Set matchingNodes = xmlDoc.SelectNodes(xpath)
If matchingNodes.Length > 0 Then
   dueDate = matchingNodes(0).Text
End If

Это прекрасно работает, и теперь я хочу извлечь самую раннюю дату, а не дату из первого узла. Но я не могу заставить работать функцию min (). Я пробовал это так:

xpath = "//XMLPKG/CASE/EVENT[OCCURRED=0][@EVENTNO='" & Format$(eventNum, "0") & "']/min(DUEDATE)"

и это:

xpath = "min(//XMLPKG/CASE/EVENT[OCCURRED=0][@EVENTNO='" & Format$(eventNum, "0") & "']/DUEDATE)"

, но обе формы дают мне ошибку «Неизвестный метод», указывающую на функцию min ().

Это (санированная) версия моего XML:

<XMLPKG>
    <CASE CASEID="1">
        <EVENT EVENTNO="23">
            <CYCLE>1</CYCLE>
            <DUEDATE>1964-11-04</DUEDATE>
            <OCCURRED>0</OCCURRED>
        </EVENT>
        <EVENT EVENTNO="23">
            <CYCLE>1</CYCLE>
            <DUEDATE>1959-11-04</DUEDATE>
            <OCCURRED>0</OCCURRED>
        </EVENT>
        <EVENT EVENTNO="23">
            <CYCLE>1</CYCLE>
            <EVENTDATE>1954-05-11</EVENTDATE>
            <OCCURRED>1</OCCURRED>
        </EVENT>
        <EVENT EVENTNO="124">
            <CYCLE>1</CYCLE>
            <EVENTDATE>1960-07-01</EVENTDATE>
            <OCCURRED>1</OCCURRED>
        </EVENT>
    </CASE>
</XMLPKG>

Что я делаю не так?

1 Ответ

1 голос
/ 26 февраля 2020

Функция min() недоступна в XPath 1.0, которая является версией XPath, предоставляемой MS XML.

Я хочу извлечь самую раннюю дату

Это невозможно в XPath 1.0, в которой можно сравнивать только те вещи, которые можно успешно преобразовать в числа. Например, выяснение СОБЫТИЯ с наименьшим значением @EVENTNO будет работать следующим образом:

//EVENT[not(@EVENTNO > //EVENT/@EVENTNO)]

Для целевых значений, которые являются произвольными строками, необходимо, чтобы строки сравнивались друг с другом лексикографически, что требуется знание сопоставления, а в XPath 1.0 это недоступно.

Но поскольку VBA может сравнивать строки, я бы использовал что-то вроде этого:

Dim eventDate As Variant, smallestDate As String

For Each eventDate In xmlDoc.SelectNodes("//EVENT[OCCURRED=0]/EVENTDATE")
   If smallestDate = "" Or eventDate.text < smallestDate Then smallestDate = eventDate.text
Next

MsgBox "Earliest event: " & smallestDate
...