为什么XSL函数`ends-with`和`matches`都抛出错误?

时间:2012-07-29 20:57:55

标签: xml xslt



我正在转换一些XML,将名为alt-title的每个元素重命名为Running_Head,前提是属性alt-title-type等于“running-head”。

<小时/> 因此,下面的代码使用了正常工作的行<xsl:when test="starts-with(@alt-title-type, 'running-head')">。但是,当我将其更改为以下任何一个时:

  • <xsl:when test="ends-with(@alt-title-type, 'running-head')">
  • <xsl:when test="matches(@alt-title-type, 'running-head')">

...抛出此错误:

  

错误:XSLTProcessor :: transformToXml()[xsltprocessor.transformtoxml]:   xmlXPathCompiledEval:堆栈中剩下2个对象。

因此,似乎函数starts-with正在运行,而ends-withmatches则不然。

<小时/> 这是我的XSL,使用starts-with,似乎正常工作:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" indent="yes" method="xml" />

    <!-- Running_Head -->
    <xsl:template match="@*|node()">
        <xsl:choose>

            <xsl:when test="starts-with(@alt-title-type, 'running-head')">
                <xsl:element name="Running_Head">
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:element>
            </xsl:when>

            <xsl:otherwise>
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:copy>
            </xsl:otherwise>

        </xsl:choose>
    </xsl:template> <!-- end of Running_Head -->

</xsl:stylesheet>

...这里是正在转换的XML:

<root-node>
    <alt-title alt-title-type="running-head">
        This is working
    </alt-title>
    <alt-title alt-title-type="asdfng-head">
        asdfasdf
    </alt-title>
    <alt-title>
        asdfasdf
    </alt-title>
    <alt-title alt-title-type="running-head">
        This is also working
    </alt-title>
</root-node>


我正在http://xslt.online-toolz.com/tools/xslt-transformation.phphttp://www.xsltcake.com/进行测试。

3 个答案:

答案 0 :(得分:3)

只有XPath 2.0具有matchesends-with功能。

在XPath 1.0中,必须编写ends-with

$suffix = substring($target, string-length($target) - string-length($suffix) + 1)

它没有正则表达式功能,但可能

包含($ target,$ substring)

如果您没有使用正则表达式元字符

,那么

就是您想要的

答案 1 :(得分:3)

正如其他人所指出的那样,XSLT 1.0处理器不支持大多数XPath 2.0函数(例如matches()ends-with())。

此外,在实现当前要求的转型中根本不需要这些功能

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="alt-title[@alt-title-type='running-head']">
  <Running_Head>
    <xsl:apply-templates select="@*|node()"/>
  </Running_Head>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于提供的XML文档

<root-node>
    <alt-title alt-title-type="running-head">
      This is working
  </alt-title>
    <alt-title alt-title-type="asdfng-head">
     asdfasdf
  </alt-title>
    <alt-title>
     asdfasdf
  </alt-title>
    <alt-title alt-title-type="running-head">
     This is also working
  </alt-title>
</root-node>

产生了正确的,正确的reault:

<root-node>
   <Running_Head alt-title-type="running-head">
      This is working
  </Running_Head>
   <alt-title alt-title-type="asdfng-head">
     asdfasdf
  </alt-title>
   <alt-title>
     asdfasdf
  </alt-title>
   <Running_Head alt-title-type="running-head">
     This is also working
  </Running_Head>
</root-node>

<强>解释

正确使用模板,匹配模式并覆盖 identity rule

答案 2 :(得分:0)

您将模板声明为XSLT 1.0,但您正在使用2.0函数ends-withmatches。使用XSL 2.0处理器(或work around the missing functions),并将您的文档声明为XSLT 2.0。

请注意,您获得的错误是这些服务使用的XSL处理器的内部错误(看起来它们无法正确处理未定义的函数)。