从java中的xpath表达式中提取所有变量引用的最安全方法

时间:2012-11-25 11:42:02

标签: java xpath saxon xpath-2.0

我正在使用java和saxon处理器。

假设我有一些XPath表达式,其中包含可能的变量refs。我也有一些自定义的xpath函数,它们可以嵌套到任意深度,可以将变量refs作为参数。所以xpath表达式非常复杂。

我想在xpath表达式中为每个变量ref提取前缀和本地名,而不进行评估。

我可以通过将一些自定义XPathVariableResolver设置为我的xpath并进行评估来提取它。但这可能会产生相当大的开销,因为我只想要提取变量refs,而不是调用耗时的自定义函数。

只是通过与'$'符号匹配的模式来做它是否安全? 可能有一些API调用很棒。或者,如果没有可用的API调用,那么我应该避免使用'$'符号(可能它可以作为字符串找到,我需要避免使用那个)。

2 个答案:

答案 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论坛