我有以下xml:
<fo:block font-weight="bold" font-style="italic">Some Text Here</fo:block>
我需要使用xsl:
将其转换为以下内容{\b\iSome Text Here\i0\b0\par}
到目前为止,我设法使用:
选择块元素<xsl:template match="fo:block">
<xsl:text>{</xsl:text>
<xsl:apply-templates />
<xsl:text>\par}</xsl:text></xsl:template>
我正在输出:{Some Text Here\par}
我正在努力使用xsl并使用xsl插入属性,有人能给我一个选择这些属性并获得所需结果的示例吗?
答案 0 :(得分:3)
使用模板模式和<xsl:sort>
指令有一种相当简单的方法。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="fo:block">
<xsl:text>{</xsl:text>
<xsl:apply-templates select="@*" mode="prefix" />
<xsl:apply-templates select="node()" />
<xsl:apply-templates select="@*" mode="suffix">
<xsl:sort order="descending"/>
</xsl:apply-templates>
<xsl:text>\par}</xsl:text>
</xsl:template>
<xsl:template match="@font-weight['bold']" mode="prefix">\b</xsl:template>
<xsl:template match="@font-style['italic']" mode="prefix">\i</xsl:template>
<xsl:template match="@font-weight['bold']" mode="suffix">\b0</xsl:template>
<xsl:template match="@font-style['italic']" mode="suffix">\i0</xsl:template>
</xsl:stylesheet>
当使用'后缀'模式时,<xsl:sort order="descending" />
以相反的顺序处理属性。
严格地说,主模板中间的select="node()"
是多余的,但是在阅读时只会处理节点而不是属性时会更清楚。
您可以通过使用以下内容替换现有的suffix
模式模板来更轻松地添加新属性:
<xsl:template match="@*" mode="suffix">
<xsl:apply-templates select="." mode="prefix" />
<xsl:text>0</xsl:text>
</xsl:template>
这只使用前缀的模板,并在末尾添加额外的0
。如果某些属性不能像这样一般地处理,你总是可以覆盖它。
答案 1 :(得分:1)
<xsl:template match="fo:block">
<xsl:text>{</xsl:text>
<xsl:if test="@font-weight = 'bold'">\b</xsl:if>
<xsl:if test="@font-style = 'italic'">\i</xsl:if>
<xsl:apply-templates />
<xsl:if test="@font-style = 'italic'">\i0</xsl:if>
<xsl:if test="@font-weight = 'bold'">\b0</xsl:if>
<xsl:text>\par}</xsl:text>
</xsl:template/>
同时检查w3schools.com以获取有关XSLT的更多信息。
答案 2 :(得分:1)
此转换更通用且易于理解:
<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个)都会产生处理结果属性根据它们的词汇顺序。