2



我正在转换一些 XML,将每个元素重命名alt-titleRunning_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/测试这个。

4

3 回答 3

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>

产生了想要的、正确的结果:

<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>

说明

正确使用模板、匹配模式和覆盖身份规则

于 2012-07-29T22:32:26.377 回答
3

只有 XPath 2.0 有matchesends-with功能。

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

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

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

包含($目标,$子字符串)

如果您不使用正则表达式元字符,这就是您想要的

于 2012-07-29T21:07:01.087 回答
0

您将模板声明为 XSLT 1.0,但您使用的是 2.0 函数ends-withmatches. 使用 XSL 2.0 处理器(或解决缺少的函数),并将您的文档声明为 XSLT 2.0。

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

于 2012-07-29T21:07:45.587 回答