2

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

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

我希望检索其 text() 类似于“{*}”的所有元素,即包含两个花括号之间的字符串,但对 xpath 不太熟悉。

我认为 xquery 语法会是这样的

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

但这因未知方法“-->matches(.<--”而失败

如果有人可以纠正我,我将不胜感激。

4

2 回答 2

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(). 如果它至少可以识别该substring()功能,您可以尝试以下解决方法:

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

应该做同样的事情。

于 2013-02-27T11:07:17.160 回答
3

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

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

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

尽管该函数仅在 XPath 2(和 XQuery,因为它是一个超集)中可用,但您可以尝试使用 full name fn:matches

在 xml 中,右斜杠必须在另一侧:

<root>
  <child1>
    <grandchild1>{tagID1}</grandchild1>
    <grandchild2>{tag2}</grandchild2>
  </child1>
  <child2>{newtag1}</child2>
</root>
于 2013-02-27T11:11:06.710 回答