1

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

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

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

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

仅通过一些与“$”符号匹配的模式来做到这一点是否安全?可能对此进行一些 API 调用会很棒。或者如果没有可用的 API 调用,那么我应该避免使用“$”符号(可能它可以定位为字符串,我需要避免使用那个)。

4

2 回答 2

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 解析框架),但还没有发布这个解析器。如果您有兴趣,请告诉我,我会发送给您。

或者,对于预定义的 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 --> 
于 2012-11-25T14:36:52.653 回答
1

使用 s9api XPathCompiler 类编译表达式:

XPathCompiler c = new Processor(false).newXPathCompiler();
c.setAllowUndeclaredVariables(true);
XPathExecutable exp = c.compile(xpathExpression);

表达式中的外部变量可以通过调用来获得:

exp.iterateExternalVariables();

顺便说一句,撒克逊人的问题是否在这里受到关注是偶然的。如果您想确定答案,请使用位于http://saxonica.plan.io/的撒克逊论坛

于 2012-11-25T17:15:57.150 回答