XPath / XQuery - 匹配包含特定值的所有元素

时间:2013-02-27 10:48:39

标签: xpath xquery

我的XML看起来有点像这样:

<root>
  <child1>
    <grandchild1>{tagID1}<grandchild1/>
    <grandchild2>{tag2}<grandchild2/>
  </child1>
  <child2>{newtag1}<child2/>
<root/>

我希望检索text()类似的所有元素&#34; {*}&#34;即包含2个curlies之间的字符串,但对xpath不太熟悉。

我认为xquery语法类似于

"//*[matches(., '{*}')]"

但是使用未知方法失败&#34; - &gt;匹配(。&lt; - &#34;

如果有人能够纠正我,我将不胜感激。

2 个答案:

答案 0 :(得分:4)

matches()函数可用于XPath 2.0,但您的XPath引擎可能只支持XPath 1.0。

如果是这种情况,你必须得到这样的结果:

//*[./text()[starts-with(., '{') and substring(., string-length(.), 1)='}']]

寻找

ANY ELEMENT
//*
   THAT HAS A TEXT NODE
   [./text()                                                               ]
            WHICH STARTS WITH A '{'
            [starts-with(., '{')                                          ]
                                 AND ENDS WITH A '}'
                                 and substring(., string-length(.), 1)='}'

如果XPath 1.0中有任何函数,substring()函数调用会执行您对ends-with()函数的期望。


编辑(以解决OP关于starts-with()未找到的评论)

我从未见过不知道starts-with()的XPath引擎。如果它至少识别substring()功能,您可以尝试以下解决方法:

//*[./text()[substring(., 1, 1)='{' and substring(., string-length(.), 1)='}']]

应该这样做。

答案 1 :(得分:3)

您的XPath看起来是正确的,但xml和正则表达式是错误的。

{}是特殊字符,必须用\来转义。并且*不能单独使用。所以正确的表达式是(使用text()而不是。,所以它不检查所有后代的文本):

//*[matches(text(), '\{.*\}')]

虽然该功能仅在XPath 2(和XQuery,因为它是超集)中可用,但您可以尝试使用全名fn:matches

在xml中,斜杠必须在另一边:

<root>
  <child1>
    <grandchild1>{tagID1}</grandchild1>
    <grandchild2>{tag2}</grandchild2>
  </child1>
  <child2>{newtag1}</child2>
</root>