Jackrabbit XPath查询:路径中带有前导号码的UUID

时间:2014-09-06 15:09:32

标签: xpath jackrabbit

当我在查询路径中的节点是以数字开头的UUID时,我认为在Jackrabbit中执行查询是一个有趣的问题。

例如,此查询正常工作,因为第二个节点以字母开头,' f':

/*/JCP/feeadeaf-1dae-427f-bf4e-842b07965a93/label//*[@sequence]

但是,如果第一个' f'被替换为' 2':

/*/JCP/2eeadeaf-1dae-427f-bf4e-842b07965a93/label//*[@sequence]

例外:

Encountered "-" at line 1, column 26.
Was expecting one of:
<IntegerLiteral> ...
<DecimalLiteral> ...
<DoubleLiteral> ...
<StringLiteral> ...
 ... rest omitted for brevity ...
     for statement: for $v in /*/JCP/2eeadeaf-1dae-427f-bf4e-842b07965a93/label//*[@sequence] return $v

我的代码一般

def queryString = queryFor path
def queryManager = session.workspace.queryManager

def query = queryManager.createQuery queryString, Query.XPATH // fails here
query.execute().nodes

我知道我的查询,带有前导星号,可能不是最好的,但我只是开始一般查询。也许使用除XPATH之外的其他语言也可以。

我在这篇文章中尝试了这个建议,在创建查询之前添加了一个保存,但没有运气

Jackrabbit Running Queries against UUID

提前感谢任何输入!

2 个答案:

答案 0 :(得分:1)

一个有效的解决方案是尝试正确地转义部分查询路径,即用于构建存储库路径的各个步骤。这个例外信息有点误导,至少对我而言,因为我认为连字符是根本原因的一部分。根本问题是节点名称中的前导数字创建了一个非法的XPATH查询,如上所述。

在这种情况下,解决方案是将各个步骤编码到路径中并构建查询的其余部分。导致只有被转义的前导号码:

/*/JCP/_x0032_eeadeaf-1dae-427f-bf4e-842b07965a93//*[@sequence]

表示步骤列表或进入Jackrabbit存储库的路径的代码:

import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.util.ISO9075;

class Path {
    List<String> steps; //...

    public String asQuery() {
        return steps.size() > 0 ? "/*" + asPathString(encodedSteps()) + "//*" : "//*";
    }

    private String asPathString(List<String> steps) {
        return '/' + StringUtils.join(steps, '/');
    }

    private List<String> encodedSteps() {
        List<String> encodedSteps = new ArrayList<>();
        for (String step : steps) {
            encodedSteps.add(ISO9075.encode(step));
        }
        return encodedSteps;
    }
}

更多说明:

如果我们转义更多的查询字符串,如:

/_x002a_/JCP/_x0032_eeadeaf-1dae-427f-bf4e-842b07965a93//_x002a_[@sequence]

或原始路径编码为整体,如:

_x002f_a_x002f_fffe4dcf0-360c-11e4-ad80-14feb59d0ab5_x002f_2cbae0dc-35e2-11e4-b5d6-14feb59d0ab5_x002f_c

查询不会产生想要的结果。

感谢@matthias_h和@LarsH

答案 1 :(得分:0)

XML元素名称不能以数字开头。请参阅STagNameNameStartChar的XML规范规则。因此,“XPath表达式”

/*/JCP/2eeadeaf-1dae-427f-bf4e-842b07965a93/label//*[@sequence]

是非法的,因为名称测试2eead...不是合法的XML名称。

因此,您不能仅使用任何旧的UUID作为XML元素名称,也不能将其用作XPath中的名称测试。但是,如果您在前面放置合法的NameStartChar(例如_),则可以使用任何UUID。

我不清楚您是否认为您已经拥有名为<2eead...>的元素的XML数据(并且正在尝试查询该元素的后代);如果是这样的话,无论生成什么工具都会被破坏,因为它会发出非法的XML。另一方面,如果<2eead...>是您自己创建的内容,那么您可以选择将元素名称修改为合法的XML名称。