在回答你的直接问题时,要匹配一个u
嵌套在一个i
嵌套在一个中,b
你会这样做
<xsl:template match="b/i/u">
您还需要模板来处理父级b
和i
<xsl:template match="b[i/u]">
<xsl:template match=b/i[u]">
但是大概你想处理以任何顺序嵌套的元素?并且为每个可能的排列编码模板会变得非常混乱,而且您还必须担心两个模板匹配相同的元素。
相反,试试这个稍微灵活一点的 XSLT,虽然不是特别优雅
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="i[parent::b|parent::u]" name="italic">
<xsl:attribute name="italic">yes</xsl:attribute>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
<xsl:template match="b[parent::i|parent::u]" name="bold">
<xsl:attribute name="bold">yes</xsl:attribute>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
<xsl:template match="u[parent::b|parent::i]" name="underline">
<xsl:attribute name="underline">yes</xsl:attribute>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>
<xsl:template match="*[self::b|self::i|self::u][not(parent::b)][not(parent::i)][not(parent::u)]">
<emphasis>
<xsl:choose>
<xsl:when test="self::b">
<xsl:call-template name="bold"/>
</xsl:when>
<xsl:when test="self::i">
<xsl:call-template name="italic"/>
</xsl:when>
<xsl:when test="self::u">
<xsl:call-template name="underline"/>
</xsl:when>
</xsl:choose>
</emphasis>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这个想法是你有模板匹配i
,b
或者u
元素有其他元素作为父元素。在这种情况下,您只需输出相关属性。
您还拥有与输出强调i
元素的最顶部b
或u
元素(即没有其他此类元素作为父元素的元素)匹配的主模板。注意命名模板的使用更简单,以避免一些代码重复。
当您将其应用于以下 XML
<test>
<b>bold</b>
<i>Italic</i>
<b><i>bold Italic</i></b>
<u><b><i>bold Italic underline</i></b></u>
</test>
以下是输出
<test>
<emphasis bold="yes">bold</emphasis>
<emphasis italic="yes">Italic</emphasis>
<emphasis bold="yes" italic="yes">bold Italic</emphasis>
<emphasis underline="yes" bold="yes" italic="yes">bold Italic underline</emphasis>
</test>