使用xslt对xml文件元素排序
我有以下xml文件:使用xslt对xml文件元素排序,xml,xslt,Xml,Xslt,我有以下xml文件: <WindowProperties> <skin>LP Connect</skin> <showToOperator>false</showToOperator> <showToVisitor>false</showToVisitor> <ChatWindow> <field> <key>direction</key> &l
<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>
低压连接
假的
假的
方向
ltr
启用CustomizedHeaderImage URL
假的
品牌类型
无图像
品牌高度
158
我想使用key元素对聊天窗口中的字段进行排序,使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>
低压连接
假的
假的
品牌高度
158
品牌类型
无图像
方向
ltr
启用CustomizedHeaderImage URL
假的
我尝试了以下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>
但这不起作用。感谢您的帮助。编辑:请参阅@JLRishe的答案,因为这是正确的做法。我下面的答案满足“文本”输出要求,但实际上更复杂,可以完成相同的任务 我已经删除了完整的示例,并保留了原始答案中的
代码,我将保留在这里,以防任何人需要在XSLT的文本输出中生成XML元素或其他标记(例如用于生成注释或其他内容)。如果您希望生成纯XML,这不是最好的方法:
原始答案:
为了让我理解这个问题,您有一个返回“文本”(而不是XML)的XSLT模板,但是您希望在输出中保留XML标记,使其看起来像XML
为此,您需要围绕要作为文本处理的XML标记的
部分,如下所示:
<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部分,但是我认为上面看起来更干净。(相同结果)
]]>
]]>
]]>
编辑:请查看@JLRishe的答案,因为这是正确的方法。我下面的答案满足“文本”输出要求,但实际上更复杂,可以完成相同的任务
我已经删除了完整的示例,并保留了原始答案中的
代码,我将保留在这里,以防任何人需要在XSLT的文本输出中生成XML元素或其他标记(例如用于生成注释或其他内容)。如果您希望生成纯XML,这不是最好的方法:
原始答案:
为了让我理解这个问题,您有一个返回“文本”(而不是XML)的XSLT模板,但是您希望在输出中保留XML标记,使其看起来像XML
为此,您需要围绕要作为文本处理的XML标记的
部分,如下所示:
<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部分,但是我认为上面看起来更干净。(相同结果)
]]>
]]>
]]>
这个简单的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>
低压连接
假的
假的
品牌高度
158
品牌类型
无图像
方向
ltr
启用CustomizedHeaderImage URL
假的
如果出于某种原因您必须使用
,您可以执行以下操作,但我不建议您这样做:
<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>
这个简单的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>
低压连接
假的
假的
品牌高度
158
品牌类型
无图像
方向
ltr
启用CustomizedHeaderImage URL
假的
如果出于某种原因您必须使用
,您可以执行以下操作,但我不建议您这样做:
<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>
这个问题的公认答案应该对您有所帮助—它返回纯文本而不是XML—XSLT的输出应该是无关的—您正在对输入进行排序,然后对其执行所需操作。这个问题的答案的要点是,您需要在字段/键上进行匹配,而不是仅仅在键上进行匹配,我想您可以将其作为xsl编写,因为我对xslt一无所知?您所说的“这返回的是纯文本而不是xml”是什么意思?显然,您希望生成XML。这个问题的公认答案应该对您有所帮助—它返回纯文本而不是XML—XSLT的输出应该是无关的—您正在对输入进行排序,然后对其执行所需操作。这个问题的答案的要点是,您需要在字段/键上进行匹配,而不是仅仅在键上进行匹配,我想您可以将其作为xsl编写,因为我对xslt一无所知?您所说的“这返回的是纯文本而不是xml”是什么意思?显然,您希望生成XML。您可以编写完整的xsl文件来生成所有XML元素吗?谢谢David的帮助help@David如果您感兴趣,我已经添加了两个简洁而完整的解决方案