当我在查询路径中的节点是以数字开头的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
提前感谢任何输入!
答案 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元素名称不能以数字开头。请参阅STag,Name和NameStartChar的XML规范规则。因此,“XPath表达式”
/*/JCP/2eeadeaf-1dae-427f-bf4e-842b07965a93/label//*[@sequence]
是非法的,因为名称测试2eead...
不是合法的XML名称。
因此,您不能仅使用任何旧的UUID作为XML元素名称,也不能将其用作XPath中的名称测试。但是,如果您在前面放置合法的NameStartChar(例如_
),则可以使用任何UUID。
我不清楚您是否认为您已经拥有名为<2eead...>
的元素的XML数据(并且正在尝试查询该元素的后代);如果是这样的话,无论生成什么工具都会被破坏,因为它会发出非法的XML。另一方面,如果<2eead...>
是您自己创建的内容,那么您可以选择将元素名称修改为合法的XML名称。