2011-01-25 79 views
3

我对XQuery非常陌生,并坦率地发现学习曲线难以置信地陡峭。XQuery:从字符串中提取数字用于比较

我有一个XML结构看起来是这样的:

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

我需要写一个返回的所有节点其中大小数值小于说1000所以我莫名其妙的XQuery语句需要确定这个数值(忽略任何文本)来执行我假设的'le'操作。

在此之上,则存在节点将具有在所有(例如,“无限单元”)没有数字,在这种情况下,需要将其视为具有说1000000

的值的可能性有没有办法做到这一点?我已经尝试过fn的各种组合:替换(blah,'\ D','')并将其转换为xs:int,但我似乎无法使其正常工作。

任何指导将不胜感激。

回答

0

也许您应该使用fn:tokenize(subject, pattern, flags)(这里是对tokenize的描述)函数来提取您的int值。 tokenize函数将返回一个数组,其int值位于数组的第一个位置。然后你可以用你的int值做任何你想要的。

为了区分给出单位的情况和“无限单位”情况,您可以使用“无限单位”做一个正则表达式fn:match或在标记之前简单地比较字符串。如果字符串是“无限单位”,则您需要处理该字符串,而在另一种情况下,您将该字符串标记为提取int值。

2

这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

1起见了一点,但我已经表明,只是一个简单的XPath表达式的足够清楚起见的位。 – 2011-01-25 22:01:34

3

使用这个XPath 1.0表达式

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

我们都清楚地知道,XPath是XQuery的一个子集,所以上面也是一个XQuery表达式。

+0

+1如果不需要匹配最大值,则表达式更好。 – 2011-01-25 21:06:20

0

重复用于

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

重复的,为了清楚起见