我有以下xml文件:
<WindowProperties>
<skin>LP Connect</skin>
<showToOperator>false</showToOperator>
<showToVisitor>false</showToVisitor>
<ChatWindow>
<field>
<key>direction</key>
<val>ltr</val>
</field>
<field>
<key>enableCustomizedHeaderImageUrl</key>
<val>false</val>
</field>
<field>
<key>brandType</key>
<val>noImage</val>
</field>
<field>
<key>brandHeight</key>
<val>158</val>
</field>
</ChatWindow>
我想使用关键元素在聊天窗口中对字段进行排序,因此xml将如下所示:
<WindowProperties>
<skin>LP Connect</skin>
<showToOperator>false</showToOperator>
<showToVisitor>false</showToVisitor>
<ChatWindow>
<field>
<key>brandHeight</key>
<val>158</val>
</field>
<field>
<key>brandType</key>
<val>noImage</val>
</field>
<field>
<key>direction</key>
<val>ltr</val>
</field>
<field>
<key>enableCustomizedHeaderImageUrl</key>
<val>false</val>
</field>
</ChatWindow>
</WindowProperties>
我尝试了以下xsl:
<ChatWindow>
<xsl:template match="ChatWindow">
<xsl:for-each select="field">
<xsl:sort select="key"/>
<key><xsl:value-of select="key"/></key>
<value><xsl:value-of select="val"/></value>
</xsl:for-each>
</xsl:template>
</ChatWindow>
但这不起作用。任何帮助表示赞赏。
答案 0 :(得分:3)
这个简单的XSLT应该可以胜任:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ChatWindow">
<xsl:copy>
<xsl:apply-templates select="field">
<xsl:sort select="key" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在样本输入上运行时,会产生:
<WindowProperties>
<skin>LP Connect</skin>
<showToOperator>false</showToOperator>
<showToVisitor>false</showToVisitor>
<ChatWindow>
<field>
<key>brandHeight</key>
<val>158</val>
</field>
<field>
<key>brandType</key>
<val>noImage</val>
</field>
<field>
<key>direction</key>
<val>ltr</val>
</field>
<field>
<key>enableCustomizedHeaderImageUrl</key>
<val>false</val>
</field>
</ChatWindow>
</WindowProperties>
如果您出于某种原因绝对必须使用<xsl:output method="text" />
,则可以执行以下操作,但我不建议这样做:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes" omit-xml-declaration="yes" />
<xsl:template match="*">
<xsl:value-of select="concat('<', name(), '>')"/>
<xsl:apply-templates />
<xsl:value-of select="concat('</', name(), '>')"/>
</xsl:template>
<xsl:template match="ChatWindow">
<xsl:value-of select="concat('<', name(), '>')"/>
<xsl:apply-templates select="field">
<xsl:sort select="key" />
</xsl:apply-templates>
<xsl:value-of select="concat('</', name(), '>')"/>
</xsl:template>
</xsl:stylesheet>
或者更长一点,但更清洁一点:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes" omit-xml-declaration="yes" />
<xsl:template name="tag">
<xsl:param name="slash" />
<xsl:value-of select="concat('<', $slash, name(), '>')"/>
</xsl:template>
<xsl:template name="cTag">
<xsl:call-template name="tag">
<xsl:with-param name="slash" select="'/'" />
</xsl:call-template>
</xsl:template>
<xsl:template match="*">
<xsl:call-template name="tag" />
<xsl:apply-templates />
<xsl:call-template name="cTag" />
</xsl:template>
<xsl:template match="ChatWindow">
<xsl:call-template name="tag" />
<xsl:apply-templates select="field">
<xsl:sort select="key" />
</xsl:apply-templates>
<xsl:call-template name="cTag" />
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
编辑:请参阅@JLRishe的回答,因为这是正确的方法。我在下面的回答满足'文本'输出要求,但实际上更复杂并完成同样的事情。
我已经删除了我的完整示例,并保留了我原始答案中的<CDATA>
代码,以防万一有人需要在XSLT的文本输出中生成XML元素或其他标记(比如说)用于生成评论或某事)。如果您希望生成纯XML,这不是最好的方法:
原始答案:
回顾一下,我理解这个问题,你有一个返回“text”(不是XML)的XSLT模板,但你希望在输出中保留XML标签,使它看起来像一样。
为此,您需要围绕要作为文本处理的XML标记的<CDATA[ ]]>
部分,如下所示:
<xsl:template match="ChatWindow">
<xsl:for-each select="field">
<xsl:sort select="key"/>
<![CDATA[<key>]]>
<xsl:value-of select="key"/>
<![CDATA[</key>]]>
<![CDATA[<value>]]>
<xsl:value-of select="val"/>
<![CDATA[</value>]]>
</xsl:for-each>
</xsl:template>
注意你也可以在中间结合CDATA部分,但我认为上面看起来更干净。 (结果相同)
<xsl:template match="ChatWindow">
<xsl:for-each select="field">
<xsl:sort select="key"/>
<![CDATA[<key>]]>
<xsl:value-of select="key"/>
<![CDATA[</key>
<value>]]>
<xsl:value-of select="val"/>
<![CDATA[</value>]]>
</xsl:for-each>
</xsl:template>