XSLT 按属性和属性值排序(排除)

XSLT sort by attribute and attribute value (with exclude)

我有以下 XML 代码:

<module>
    <component>
        <output>
        <output-test>
        <exclude-output/>
        <orderEntry type="specific"/>
        <orderEntry type="other"/>
        <orderEntry type="module" module-name="module1"/>
        <orderEntry type="module" module-name="module3"/>
        <orderEntry type="module" module-name="module2"/>
        <orderEntry type="library" name="library1"/>
        <orderEntry type="library" name="library3"/>
        <orderEntry type="module" module-name="module4"/>
        <orderEntry type="library" name="library2"/>
    </component>
</module>

我想要输出:

<module>
    <component>
        <output>
        <output-test>
        <exclude-output/>
        <orderEntry type="specific"/>
        <orderEntry type="other"/>
        <orderEntry type="module" module-name="module1"/>
        <orderEntry type="module" module-name="module2"/>
        <orderEntry type="module" module-name="module3"/>
        <orderEntry type="module" module-name="module4"/>
        <orderEntry type="library" name="library1"/>
        <orderEntry type="library" name="library2"/>
        <orderEntry type="library" name="library3"/>
    </component>
</module>

我不完全确定这是否满足您的要求,但您可以明确地 select 将您想要的放在单独的 xsl:apply-templates 中排在第一位,然后 select 其他的 select对他们的 type 属性

进行排序
<xsl:apply-templates select="orderEntry[@type='specific' or @type='other']" />
<xsl:apply-templates select="orderEntry[@type!='specific' and @type!='other']">
   <xsl:sort select="@type" order="descending" />
   <xsl:sort select="@module-name" order="ascending" />
   <xsl:sort select="@name" order="ascending" />
</xsl:apply-templates>

看目前的预期输出,好像所有的type属性都是降序排列的,所以你可以简化成这样

<xsl:apply-templates select="orderEntry">
    <xsl:sort select="@type" order="descending" />
    <xsl:sort select="@module-name" order="ascending" />
    <xsl:sort select="@name" order="ascending" />
</xsl:apply-templates>

试试这个 XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:template match="component">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()[not(self::orderEntry)]"/>
            <xsl:apply-templates select="orderEntry">
                <xsl:sort select="@type" order="descending" />
                <xsl:sort select="@module-name" order="ascending" />
                <xsl:sort select="@name" order="ascending" />
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

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

请注意,如果您真的想对未按字母顺序排列的 type 属性进行排序,您可以这样做:

<xsl:apply-templates select="orderEntry">
    <xsl:sort select="string-length(substring-before('specific,other,module,library',@type))" order="ascending" />
    <xsl:sort select="@module-name" order="ascending" />
    <xsl:sort select="@name" order="ascending" />
</xsl:apply-templates>