XSLT - 模板匹配冲突
XSLT - template match conflicts
我有一个 xml 如下,
<doc>
<a ref="style1"></a>
<a ref="style1"></a>
<a ref="style1" ></a>
<a ref="style2"></a>
<a ref="style2"></a>
<doc>
我需要将 xslt 中的单独内容添加到 <a ref="style1">
节点和 <a ref="style2">
节点。我可以在 <xsl:template match ="a[@ref = 'style1']">
和 <xsl:template match ="@ref = 'style2'">
模板中编写那些需要的逻辑。
我还需要将动态 ID 添加到 <a>
节点。所以我写了下面的模板来添加所需的 ids
//adds dynamic id's to `<a>` nodes
<xsl:template match="a[@ref='style1' or @ref='style2']">
<a ref="style">
<xsl:attribute name="id">
<xsl:number count="a[@ref='style1' or a[@ref='style2']"/>
</xsl:attribute>
</a>
</xsl:template>
我的预期输出如下,
<doc>
<a ref="style" id="1"></a>
<a ref="style" id="2"></a>
<a ref="style" id="3"></a>
<a ref="style" id="4"></a>
<a ref="style" id="5"></a>
<doc>
但由于我在两个地方(<xsl:template match ="a[@ref = 'style1']">
和 <xsl:template match="a[@ref='style1' or @ref='style2']">
)使用了相同的模板,所以在氧气编辑器中出现 "Ambiguous rule match"
错误。在这种情况下,我如何组织我的代码结构来避免这个错误?
一个选项是使处理 style1
和 style2
的模板成为模版模板。
XML 输入
<doc>
<a ref="style1"/>
<a ref="style1"/>
<a ref="style1"/>
<a ref="style2"/>
<a ref="style2"/>
</doc>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a[@ref='style1' or @ref='style2']" mode="addId">
<xsl:apply-templates select="@*"/>
<xsl:attribute name="ref" select="'style'"/>
<xsl:attribute name="id">
<xsl:number count="a[@ref=('style1','style2')]"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="a[@ref='style1']">
<xsl:copy>
<xsl:apply-templates select="." mode="addId"/>
<xsl:apply-templates select="node()"/>
<special>processed style1</special>
</xsl:copy>
</xsl:template>
<xsl:template match="a[@ref='style2']">
<xsl:copy>
<xsl:apply-templates select="." mode="addId"/>
<xsl:apply-templates select="node()"/>
<special>processed style2</special>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出
<doc>
<a ref="style" id="1">
<special>processed style1</special>
</a>
<a ref="style" id="2">
<special>processed style1</special>
</a>
<a ref="style" id="3">
<special>processed style1</special>
</a>
<a ref="style" id="4">
<special>processed style2</special>
</a>
<a ref="style" id="5">
<special>processed style2</special>
</a>
</doc>
根据您对 style1
和 style2
的个人模板的处理方式,您是否可以向通用模板添加更高的优先级,然后使用 xsl:next-match
匹配较低优先级的模板(个别处理)...
XSLT 2.0(使用上面的输入产生相同的输出)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a[@ref='style1' or @ref='style2']" priority="1">
<a ref="style">
<xsl:apply-templates select="@*"/>
<xsl:attribute name="id">
<xsl:number count="a[@ref=('style1','style2')]"/>
</xsl:attribute>
<xsl:next-match/>
</a>
</xsl:template>
<xsl:template match="a[@ref='style1']">
<special>processed style1</special>
</xsl:template>
<xsl:template match="a[@ref='style2']">
<special>processed style2</special>
</xsl:template>
</xsl:stylesheet>
我有一个 xml 如下,
<doc>
<a ref="style1"></a>
<a ref="style1"></a>
<a ref="style1" ></a>
<a ref="style2"></a>
<a ref="style2"></a>
<doc>
我需要将 xslt 中的单独内容添加到 <a ref="style1">
节点和 <a ref="style2">
节点。我可以在 <xsl:template match ="a[@ref = 'style1']">
和 <xsl:template match ="@ref = 'style2'">
模板中编写那些需要的逻辑。
我还需要将动态 ID 添加到 <a>
节点。所以我写了下面的模板来添加所需的 ids
//adds dynamic id's to `<a>` nodes
<xsl:template match="a[@ref='style1' or @ref='style2']">
<a ref="style">
<xsl:attribute name="id">
<xsl:number count="a[@ref='style1' or a[@ref='style2']"/>
</xsl:attribute>
</a>
</xsl:template>
我的预期输出如下,
<doc>
<a ref="style" id="1"></a>
<a ref="style" id="2"></a>
<a ref="style" id="3"></a>
<a ref="style" id="4"></a>
<a ref="style" id="5"></a>
<doc>
但由于我在两个地方(<xsl:template match ="a[@ref = 'style1']">
和 <xsl:template match="a[@ref='style1' or @ref='style2']">
)使用了相同的模板,所以在氧气编辑器中出现 "Ambiguous rule match"
错误。在这种情况下,我如何组织我的代码结构来避免这个错误?
一个选项是使处理 style1
和 style2
的模板成为模版模板。
XML 输入
<doc>
<a ref="style1"/>
<a ref="style1"/>
<a ref="style1"/>
<a ref="style2"/>
<a ref="style2"/>
</doc>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a[@ref='style1' or @ref='style2']" mode="addId">
<xsl:apply-templates select="@*"/>
<xsl:attribute name="ref" select="'style'"/>
<xsl:attribute name="id">
<xsl:number count="a[@ref=('style1','style2')]"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="a[@ref='style1']">
<xsl:copy>
<xsl:apply-templates select="." mode="addId"/>
<xsl:apply-templates select="node()"/>
<special>processed style1</special>
</xsl:copy>
</xsl:template>
<xsl:template match="a[@ref='style2']">
<xsl:copy>
<xsl:apply-templates select="." mode="addId"/>
<xsl:apply-templates select="node()"/>
<special>processed style2</special>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出
<doc>
<a ref="style" id="1">
<special>processed style1</special>
</a>
<a ref="style" id="2">
<special>processed style1</special>
</a>
<a ref="style" id="3">
<special>processed style1</special>
</a>
<a ref="style" id="4">
<special>processed style2</special>
</a>
<a ref="style" id="5">
<special>processed style2</special>
</a>
</doc>
根据您对 style1
和 style2
的个人模板的处理方式,您是否可以向通用模板添加更高的优先级,然后使用 xsl:next-match
匹配较低优先级的模板(个别处理)...
XSLT 2.0(使用上面的输入产生相同的输出)
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a[@ref='style1' or @ref='style2']" priority="1">
<a ref="style">
<xsl:apply-templates select="@*"/>
<xsl:attribute name="id">
<xsl:number count="a[@ref=('style1','style2')]"/>
</xsl:attribute>
<xsl:next-match/>
</a>
</xsl:template>
<xsl:template match="a[@ref='style1']">
<special>processed style1</special>
</xsl:template>
<xsl:template match="a[@ref='style2']">
<special>processed style2</special>
</xsl:template>
</xsl:stylesheet>