这种转换更加通用和可扩展:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:variable name="vAttributesResult">
<xsl:call-template name="processAttributes"/>
</xsl:variable>
<xsl:value-of select=
"concat(substring-before($vAttributesResult, ' '),
.,
substring-after($vAttributesResult, ' ')
)
"/>
</xsl:template>
<xsl:template name="processAttributes">
<xsl:param name="pattrList" select="@*"/>
<xsl:param name="pResult" select="' '"/>
<xsl:choose>
<xsl:when test="not($pattrList)">
<xsl:value-of select="$pResult"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vthisResult">
<xsl:apply-templates select="$pattrList[1]">
<xsl:with-param name="pResult" select="$pResult"/>
</xsl:apply-templates>
</xsl:variable>
<xsl:call-template name="processAttributes">
<xsl:with-param name="pattrList" select="$pattrList[position()>1]"/>
<xsl:with-param name="pResult" select="$vthisResult"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@font-weight[.='bold']">
<xsl:param name="pResult"/>
<xsl:value-of select="concat('\b', $pResult, '\b0')"/>
</xsl:template>
<xsl:template match="@font-style[.='italic']">
<xsl:param name="pResult"/>
<xsl:value-of select="concat('\i', $pResult, '\i0')"/>
</xsl:template>
</xsl:stylesheet>
当应用于提供的XML文档(已更正为格式良好)时:
<fo:block font-weight="bold" font-style="italic"
xmlns:fo="some:fo">Some Text Here</fo:block>
期望的结果已经生成:
\i\bSome Text Here\b0\i0
请注意:
您可以轻松地为任意数量的新属性/值组合添加处理方式 -- 只需为新属性添加一个新模板即可。
如果顺序很重要,请使用这些模板来处理属性:
--
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:text>{</xsl:text>
<xsl:apply-templates select="@*">
<xsl:with-param name="pSuff" select="''"/>
<xsl:sort select="position()"/>
</xsl:apply-templates>
<xsl:apply-templates select="node()" />
<xsl:apply-templates select="@*">
<xsl:with-param name="pSuff" select="'0'"/>
<xsl:sort select="position()" order="descending"/>
</xsl:apply-templates>
<xsl:text>\par}</xsl:text>
</xsl:template>
<xsl:template match="@font-weight['bold']">
<xsl:param name="pSuff"/>
<xsl:value-of select="concat('\b',$pSuff)"/>
</xsl:template>
<xsl:template match="@font-style['italic']">
<xsl:param name="pSuff"/>
<xsl:value-of select="concat('\i',$pSuff)"/>
</xsl:template>
</xsl:stylesheet>
这个转换借鉴了 @Flynn1169 的答案思路,并显著简化了它(只有 3 个模板而不是 t,也没有模式),最重要的是,按属性的词法顺序呈现结果。
在这种情况下,结果匹配属性的词法顺序,而不是它们排序后的名称!:
如果我们有这个 XML 文档:
<fo:block font-style="italic" font-weight="bold"
xmlns:fo="some:fo">Some Text Here</fo:block>
现在的结果是:
{\i\bSome Text Here\b0\i0\par}
备注:虽然在XPath数据模型中没有“属性顺序”这样的概念,但我正在使用的所有推送式模式的XSLT处理器(超过9个)都会按照它们的词汇顺序处理属性。