这是我的转变:
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/root">
<output>
<xsl:apply-templates select="outer[@type='foo']/inner"/>
</output>
</xsl:template>
<xsl:template match="outer[@type='foo']/inner[@type='bar1' or @type='bar2' or @type='bar3' or @type='bar4']">
<item>
<xsl:value-of select="text()"/>
</item>
</xsl:template>
<xsl:template match="outer[@type='foo']/inner">
<xsl:message terminate="yes">
<xsl:value-of select="concat('Unexpected type: ', @type)"/>
</xsl:message>
</xsl:template>
</xsl:transform>
这是我的意见:
<root>
<outer type="foo">
<inner type="bar2">bar2</inner>
</outer>
</root>
当我对输入执行转换时,Xalan退出并发生致命错误,这是由第三个<xsl:message terminate="yes">
中的<xsl:template>
引起的。为什么?不应该是第二个更专业的<xsl:template>
匹配吗?
答案 0 :(得分:1)
根据http://lenzconsulting.com/how-xslt-works/#priority
,两个匹配的表达式的优先级均为.5所以你的模板是冲突的。如何处理1个单一模板中的所有内容?
<xsl:template match="outer[@type='foo']/inner">
<xsl:choose>
<xsl:when test="@type='bar1' or @type='bar2' or @type='bar3' or @type='bar4'">
<item>
<xsl:value-of select="text()"/>
</item>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
<xsl:value-of select="concat('Unexpected type: ', @type)"/>
</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
答案 1 :(得分:1)
另一个解决方案是简单地让2个模板交易位置:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/root">
<output>
<xsl:apply-templates select="outer[@type='foo']/inner"/>
</output>
</xsl:template>
<xsl:template match="outer[@type='foo']/inner">
<xsl:message terminate="yes">
<xsl:value-of select="concat('Unexpected type: ', @type)"/>
</xsl:message>
</xsl:template>
<xsl:template match="outer[@type='foo']/inner[@type='bar1' or @type='bar2' or @type='bar3' or @type='bar4']">
<item>
<xsl:value-of select="text()"/>
</item>
</xsl:template>
</xsl:transform>
虽然这可能不是很干净,但你应该保持原样并明确地将prio设置为高于.5而不是更专业的模板:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/root">
<output>
<xsl:apply-templates select="outer[@type='foo']/inner"/>
</output>
</xsl:template>
<xsl:template match="outer[@type='foo']/inner[@type='bar1' or @type='bar2' or @type='bar3' or @type='bar4']" priority="1">
<item>
<xsl:value-of select="text()"/>
</item>
</xsl:template>
<xsl:template match="outer[@type='foo']/inner">
<xsl:message terminate="yes">
<xsl:value-of select="concat('Unexpected type: ', @type)"/>
</xsl:message>
</xsl:template>
</xsl:transform>