我正在转换一些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-with
和matches
则不然。
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.php和http://www.xsltcake.com/进行测试。
答案 0 :(得分:3)
只有XPath 2.0具有matches
和ends-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-with
和matches
。使用XSL 2.0处理器(或work around the missing functions),并将您的文档声明为XSLT 2.0。
请注意,您获得的错误是这些服务使用的XSL处理器的内部错误(看起来它们无法正确处理未定义的函数)。