按顺序对元素进行XSL排序,同时还添加空格

时间:2017-11-02 13:34:25

标签: xml sorting xslt

我有一个xsl按顺序排列elemets,我也想在特定节点后添加空格 例如:

<?xml version="1.0"?>
<catalog>
   <fruits criteria="XXX">
        <color>XXX</color>
        <type>XXX</type>
        <taste>XXX</taste>
    </fruits>
    <veggies>
        <carrot>XXXX</carrot>
        <beetroot>XXX</beetroot>
        <pumpkin>XXX</pumpkin>
    </veggies>
    <something>
        <xxx>42343</xxx>
    </something>
</catalog>

XSl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="fruits">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="type"/>
            <xsl:apply-templates select="taste"/>
            <xsl:apply-templates select="color"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="veggies/* | fruits/* | something/*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
        <xsl:if test="following-sibling::*">
            <xsl:text>&#x0A;</xsl:text>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

预期结果:

<?xml version="1.0"?>
<catalog>
    <fruits criteria="XXX">
        <type>XXX</type>
        <taste>XXX</taste>
        <color>XXX</color>    
    </fruits>

    <veggies>
        <carrot>XXXX</carrot>
        <beetroot>XXX</beetroot>
        <pumpkin>XXX</pumpkin>
    </veggies>

    <something>
        <xxx>42343</xxx>
    </something>
</catalog>

它不会添加空格,但如果我删除排序xsl模板,它会起作用。排序和间距都不能协同工作。想法?

1 个答案:

答案 0 :(得分:1)

我认为你在错误的匹配模式的模板中创建了空格,一般来说,这些东西在XSLT 1.0中更容易,你可以用xsl:next-match将任务委托给优先级较低的模板:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

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

    <xsl:template match="fruits">
        <xsl:copy>
            <xsl:apply-templates select="@*, type, taste, color"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="catalog/*[following-sibling::*]">
        <xsl:next-match/>
        <xsl:text>&#10;&#10;</xsl:text>
    </xsl:template>

</xsl:transform>

http://xsltransform.net/6pS1zDR

使用XSLT 1.0,您必须命名模板并使用call-template而不是next-match:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="catalog/fruits" name="fruits" priority="5">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="type"/>
            <xsl:apply-templates select="taste"/>
            <xsl:apply-templates select="color"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="catalog/fruits[following-sibling::*]" priority="5">
        <xsl:call-template name="fruits"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>

    <xsl:template match="catalog/*[following-sibling::*]">
        <xsl:call-template name="identity"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>

</xsl:transform>

最后,使用XSLT 3,您可以专注于只为需要特殊处理的元素编写两个模板:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

    <xsl:template match="fruits">
        <xsl:copy>
            <xsl:apply-templates select="@*, type, taste, color"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="catalog/*[following-sibling::*]">
        <xsl:next-match/>
        <xsl:text>&#10;&#10;</xsl:text>
    </xsl:template>

</xsl:stylesheet>