Как мы можем присоединиться к XPATH, используя версию 1.0? - PullRequest
0 голосов
/ 16 апреля 2020

Я пытаюсь получить номер и имена человека и цену аренды автомобиля, которая составляет> 300

ниже, мой XML пример:

<rent number="101111">
    <car>
        <startDate>2018-02-08</startDate>
        <endDate>2018-03-05</endDate>
        <Location>Toranto</Location>
        <carType>BMW</carType>
        <transmissionType>Automatic</transmissionType>
    </car>
    <person>
        <licenseNumber> 02389749372 </licenseNumber>
        <name>Alexa Steve</name>
        <dob>1999-03-01</dob>
        <phone>
            <type>Home</type>
            <number>44 010 1111 4567</number>
        </phone>
        <email> Alexa@steve.ca</email>
    </person>
    <price>
        <Rate>100.50</Rate>
    </price>
</rent>



<rent number="103311">
    <car>
        <startDate>2018-07-01</startDate>
        <endDate>2018-09-05</endDate>
        <Location>ottawa</Location>
        <carType>audi 8</carType>
        <transmissionType>Automatic</transmissionType>
    </vehicle>
    <person>
        <licenseNumber> 033329372 </licenseNumber>
        <name>mike lornco</name>
        <dob>1960-03-03</dob>
        <phone>
            <type>Home</type>
            <number>44 010 1111 3333</number>
        </phone>
        <email> mikelornokorenco@gmail.com</email>
    </person>
    <price>
        <Rate>300.50</Rate>
    </price>
</rent>

я пытаюсь получить водительские права и возраст человека, у которого есть прокат автомобиля, который> = 300

отдельный запрос, который работает:

//price[Rate >= 300]
//person/name/licenseNumber
//person/name
//car/carType

Ответы [ 3 ]

1 голос
/ 16 апреля 2020

Полагаю, вы, вероятно, используете XPath 1.0 (потому что люди, использующие более поздние версии, обычно так говорят, а также потому, что если бы вы использовали более позднюю версию, это было бы легко).

что я я пытаюсь сделать это, чтобы получить водительские права, а также имена и возраст человека и стоимость аренды автомобиля, которая составляет> = 300 в одиночку [вместе с?] с типом автомобиля

Одна трудность здесь XPath 1.0 не слишком силен для выдачи составного результата, подобного этому. Что вы на самом деле хотите вернуть? Набор узлов (если да, то какие узлы?). Возможно отформатированная строка, содержащая необходимую информацию? Если вы хотите построить составной результат как XML, то вам не повезло, поскольку XPath 1.0 не может создавать узлы, он может только выбирать их.

Другая сложность заключается (в соответствии с вашим вопрос) занимаюсь объединением. XPath 1.0 не является «реляционно полным» в терминологии Кодда, то есть не имеет эквивалентной мощности для исчисления предикатов первого порядка, что означает, что не все объединения являются выразимыми.

Поэтому мой совет заключается в том, что XPath 1.0 - неподходящий инструмент для работы. Вы должны смотреть на XQuery, XPath 2.0 или XSLT. Есть ли у вас технологические ограничения, которые мешают вам использовать такие инструменты?

0 голосов
/ 16 апреля 2020

Эти выражения должны работать (результат - это отформатированная строка, содержащая необходимую информацию):

Xpath 1.0:

concat(normalize-space(//Rate[.>=300]/preceding::licenseNumber[1]),"|",//Rate[.>=300]/preceding::name[1],"|",2020-substring(//Rate[.>=300]/preceding::dob[1],1,4))

Xpath 2.0:

concat(replace(string-join(//Rate[.>=300]/preceding::person[1]/*[position()<3],"|"),"\W(\d+)\W(|.+)","$1$2"),"|",year-from-date(current-date())-year-from-date(//Rate[.>=300]/preceding::dob[1]))

Вывод (номер лицензии, имя, возраст):

'033329372|mike lornco|60'

Для проверки: https://www.freeformatter.com/xpath-tester.html

Я полагаю, у вас есть несколько предметов. Вы можете выполнить итерацию с помощью:

concat(normalize-space((//Rate[.>=300]/preceding::licenseNumber[1])[x]),"|",(//Rate[.>=300]/preceding::name[1])[x],"|",2020-number(substring((//Rate[.>=300]/preceding::dob[x])[1],1,4)))

Где [x] начинается с 1 до XXX.

EDIT: Ваши данные XML содержат ошибки. Вот что я использовал:

<data>
<rent number="101111">
    <car>
        <startDate>2018-02-08</startDate>
        <endDate>2018-03-05</endDate>
        <Location>Toranto</Location>
        <carType>BMW</carType>
        <transmissionType>Automatic</transmissionType>
    </car>
    <person>
        <licenseNumber> 02389749372 </licenseNumber>
        <name>Alexa Steve</name>
        <dob>1999-03-01</dob>
        <phone>
            <type>Home</type>
            <number>44 010 1111 4567</number>
        </phone>
        <email> Alexa@steve.ca</email>
    </person>
    <price>
        <Rate>100.50</Rate>
    </price>
</rent>
<rent number="103311">
    <car>
        <startDate>2018-07-01</startDate>
        <endDate>2018-09-05</endDate>
        <Location>ottawa</Location>
        <carType>audi 8</carType>
        <transmissionType>Automatic</transmissionType>
    </car>
    <person>
        <licenseNumber> 033329372 </licenseNumber>
        <name>mike lornco</name>
        <dob>1960-03-03</dob>
        <phone>
            <type>Home</type>
            <number>44 010 1111 3333</number>
        </phone>
        <email> mikelornokorenco@gmail.com</email>
    </person>
    <price>
        <Rate>300.50</Rate>
    </price>
</rent>
</data>

EDIT 2: Объяснение выражения XPath 1.0:

Мы используем concat, чтобы объединить результат нескольких операций (каждая из которых отделена от a ","):

normalize-space(//Rate[.>=300]/preceding::licenseNumber[1]): мы получаем номер лицензии человека, имеющего прокат автомобиля, который составляет> = 300 (синтаксис XPath). Мы используем normalize-space () для удаления начальных и закрывающих пробелов.

Мы ставим «|» чтобы отделить результат от следующего.

//Rate[.>=300]/preceding::name[1]: мы получаем имя человека, у которого есть прокат автомобиля,> 300 = (синтаксис XPath).

2020-substring(//Rate[.>=300]/preceding::dob[1],1,4) : мы получаем дату рождения человека, у которого прокат автомобилей составляет> = 300. С этой датой рождения мы извлекаем с помощью susbtring () год рождения («1,4» означает, что мы хотим получить значения от символа 1 до символа 4) , Наконец, мы вычтем это значение из 2020 года, чтобы получить возраст человека.

РЕДАКТИРОВАТЬ 3: XPath 1.0, чтобы получить самое длинное бронирование, см. Как получить самое длинное бронирование в XPATH 1.0?

0 голосов
/ 16 апреля 2020

Я думаю, это то, что вы ищете, где вы можете получить возраст на основе DOB в xml.

xs:integer((current-date()-xs:date(//price[Rate >= 300]/parent::rent/person/dob/text())) div xs:dayTimeDuration('P365D'))

Снимок экрана: enter image description here

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