【问题标题】:XQuery: extract number from string to use in comparisonXQuery:从字符串中提取数字以用于比较
【发布时间】:2011-01-25 13:33:20
【问题描述】:

我是 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 的所有节点。所以我需要以某种方式确定这个数值(忽略任何文本)来执行我假设是“le”操作。

除此之外,节点可能根本没有数字(例如“无限单位”),在这种情况下,它需要被视为具有 1000000 的值。

有没有办法做到这一点?我尝试了 fn:replace(blah, '\D', '') 和转换为 xs:int 的各种组合,但我似乎无法让它工作。

任何指导将不胜感激。

【问题讨论】:

    标签: parsing xpath numbers xquery


    【解决方案1】:

    使用这个 XPath 1.0 表达式

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

    众所周知,XPath是XQuery的一个子集,所以上面也是一个XQuery表达式。

    【讨论】:

    • +1 如果不需要匹配最大值,则更好的表达方式。
    • @Alejandro:“无限节点”的意思就是:“比什么都大。”
    • 是的,但您知道NaN 有特殊规则,这就是双重否定表达式(“不大于”而不是“小于”)的原因。因此,对于“大于”500,您需要“不小于”,如/root/product[not(500 &gt;= substring-before(size, ' '))]。这对每个人来说都不是很清楚。
    • @Alejandro:总有一些东西“不是每个人都清楚”——如果他们只是复制并使用我的答案中的表达作为“填空”表达,他们不需要太深入的了解。
    【解决方案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>
    

    【讨论】:

    • +1,但我已经证明,只需一个简单的 XPath 表达式就足够了。
    【解决方案3】:

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

    要区分给出单位的情况和“无限单位”的情况,您可以使用“无限单位”执行正则表达式fn:match,或者在标记化之前简单地比较字符串。如果字符串是“Unlimited units”,则您认为这是必要的,而在另一种情况下,您对字符串进行标记以提取 int 值。

    【讨论】:

      【解决方案4】:

      为了清楚起见,有点重复

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

      为了清楚起见,有点重复

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        • 2017-05-30
        • 2013-05-06
        相关资源
        最近更新 更多