XML元素排序

时间:2016-12-29 12:04:18

标签: xml xslt

我有以下XML文件:

<?xml version="1.0" encoding="UTF-8"?>
        <table>
            <row>
                <description2>ABC</description2>
            </row>
            <row>
                <description2>DEF</description2>
            </row>
            <row>
                <description2>GHI</description2>
            </row>
            <row>
                <description1>JKL</description1>
                <message>msg1</message>
            </row>
            <row>
                <description1>MNO</description1>
                <message>msg2</message>
            </row>
        </table>

我希望包含 description2 子节点的所有行节点显示在包含 description

的行节点之后

所以我的结果XML如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<table>
    <row>
        <description1>JKL</description1>
        <message>msg1</message>
    </row>
    <row>
        <description1>MNO</description1>
        <message>msg2</message>
    </row>
    <row>
        <description2>ABC</description2>
    </row>
    <row>
        <description2>DEF</description2>
    </row>
    <row>
        <description2>GHI</description2>
    </row>
</table>

如何在XSLT中实现这一目标?

1 个答案:

答案 0 :(得分:0)

尝试这样的事情:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="table">
        <xsl:apply-templates select="row/description1/.."/>
        <xsl:apply-templates select="row/description2/.."/>
    </xsl:template>
</xsl:stylesheet>

注意如何在第二个模板中选择目标元素:

  • row - 找到子row元素,
  • description1 - 找到description1元素(特定row的子元素),
  • .. - 向上一级,到包含刚找到的description1元素的行,然后返回这些行。

然后对description2进行了类似的选择(实际上 - 包含这些description2元素的行)。

另一种解决方案,具有真正的排序功能,尤其适用于您的源XML包含以其他数字终止的description标记。

将第二个模板替换为:

<xsl:template match="table">
   <xsl:for-each select="row">
        <xsl:sort select="*[1]/name()" />
        <xsl:sort select="*[1]" />
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:for-each>
</xsl:template>

第一个排序键是第一个子标签(description...)的名称,第二个是其值。

如果您不需要此功能,只需删除第二条sort指令。