我正在使用java和saxon处理器。
假设我有一些XPath表达式,其中包含可能的变量refs。我也有一些自定义的xpath函数,它们可以嵌套到任意深度,可以将变量refs作为参数。所以xpath表达式非常复杂。
我想在xpath表达式中为每个变量ref提取前缀和本地名,而不进行评估。
我可以通过将一些自定义XPathVariableResolver设置为我的xpath并进行评估来提取它。但这可能会产生相当大的开销,因为我只想要提取变量refs,而不是调用耗时的自定义函数。
只是通过与'$'符号匹配的模式来做它是否安全? 可能有一些API调用很棒。或者,如果没有可用的API调用,那么我应该避免使用'$'符号(可能它可以作为字符串找到,我需要避免使用那个)。
答案 0 :(得分:1)
如果声明了每个变量(在单个样式表模块中必须如此,您只需使用此XPath 2.0表达式:
doc(yourUri)//xsl:variable/@name/string()
其中名称空间前缀"xsl"
必须注册到名称空间"http://www.w3.org/1999/XSL/Transform"
。
或者来自XSLT样式表:
document(yourUri)//xsl:variable/@name/string()
您可能还需要获取所有参数名称:
doc(yourUri)//xsl:param/@name/string()
或者,变量和参数名称:
doc(yourUri)//*[self::xsl:variable or self::xsl:param]/@name/string()
现在,这不会得到XPath表达式中定义的变量集。要做到这一点,你需要一个XPath 2.0解析器(和词法分析器)。在过去,我开发了这样的(使用 FXSL parsing framework ),但尚未发布此解析器。如果您有兴趣,请告诉我,我会发给您。
或者,对于预定义的XSLT属性名称子集,您可以分析它们的值并检索可能后跟空格的美元,然后是名称。所有这一切都不能在单引号或双引号内。这样的正则表达式并不难写。
作为最后一步,您必须对如此获得的变量引用进行重复数据删除 - 例如使用xsl:for-each-group
<强>更新强>:
这是我正在使用的XPath 2.0语法的一个片段:
VariableReference : '$' QName
QName : QNAME2
| OR
| AND
| EQ
| NE
| LT
| LE
| GT
| GE
| IS
| TO
| DIV
| IDIV
| MOD
| UNION
| INTERSECT
| EXCEPT
| THEN
| ELSE
| IN
| RETURN
| SATISFIES
终端符号QNAME2以这种方式在词法分析器中定义:
([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*
当然,即使在此之前,必须确保(认识到)这不是字符串文字的一部分,在我的词法分析器中我定义为:
("([^"])*")+
|
('([^'])*')+
此外,您应该跳过评论中的所有内容。我有这个正则表达式评论开始和评论结束:
(\(:) <!-- Comment start -->
|
(:\)) <!-- Comment end -->
答案 1 :(得分:1)
使用s9api XPathCompiler类编译表达式:
XPathCompiler c = new Processor(false).newXPathCompiler();
c.setAllowUndeclaredVariables(true);
XPathExecutable exp = c.compile(xpathExpression);
然后可以通过调用:
获得表达式中的外部变量exp.iterateExternalVariables();
顺便说一句,撒克逊人的问题是否会在这里得到关注,这是一次又一次的尝试。如果您想确定答案,请使用http://saxonica.plan.io/
上的Saxon论坛