XQuery: извлечь номер из строки для использования в сравнении - PullRequest
4 голосов
/ 25 января 2011

Я очень плохо знаком с XQuery и, честно говоря, считаю, что кривая обучения невероятно крутая.

У меня есть структура XML, которая выглядит примерно так:

<root>
    <product>
        <size>500 units</size>
    </product>
    <product>
        <size>1000 units</size>
    </product>
    <product>
        <size>Unlimited units</size>
    </product>
</root>

Мне нужно написать оператор XQuery, который возвращает все узлы, в которых числовое значение в size меньше, чем, скажем, 1000. Поэтому мне как-то нужно определить это числовое значение (игнорируя любой текст), чтобы выполнить ' ле операция я предполагаю.

Кроме того, существует вероятность того, что у узла вообще не будет цифр (например, «Неограниченные единицы»), и в этом случае его необходимо рассматривать как имеющее значение, скажем, 1000000.

Есть ли способ сделать это? Я пробовал различные комбинации fn: replace (blah, '\ D', '') и приведение к xs: int, но я не могу заставить его работать.

Любое руководство будет с благодарностью.

Ответы [ 4 ]

3 голосов
/ 25 января 2011

Используйте это выражение XPath 1.0 :

/root/product[not(number(substring-before(size, ' ')) >= 1000)]

Как мы все хорошо знаем, XPath является подмножеством XQuery, поэтому вышеприведенное также является выражением XQuery.

2 голосов
/ 25 января 2011

Это XQuery:

for $vProduct in /root/product
let $vUnits := number(substring-before($vProduct/size,'units'))
let $vSize := if ($vUnits)
              then $vUnits
              else 1000000
where $vSize le 1000
return $vProduct

Выход:

<product>
    <size>500 units</size>
</product>
<product>
    <size>1000 units</size>
</product>
0 голосов
/ 22 ноября 2011

Немного повторения ради ясности

/root/product[not(substring-before(size," ") castable as xs:integer) or xs:integer(substring-before(size," ")) < 1000]

Немного повторения ради ясности

0 голосов
/ 25 января 2011

Вероятно, вам следует использовать функцию fn:tokenize(subject, pattern, flags) (здесь приведено описание tokenize ) для извлечения значений int. Функция tokenize вернет массив с вашими значениями int в первой позиции массива. Затем вы можете делать с вашими значениями int все, что хотите.

Чтобы провести различие между случаями, когда заданы единицы, и случаем "Неограниченные единицы", вы можете сделать регулярное выражение fn:match с "Неограниченными единицами" или просто сравнить строку перед токенизацией. Если строка "Неограниченные единицы", вы должны обработать это необходимо, а в другом случае вы токенизируете строку для извлечения значения int.

...