【问题标题】:How do I sort using XSLT based on XML nodes' attribute value?如何根据 XML 节点的属性值使用 XSLT 进行排序?
【发布时间】:2012-09-06 15:14:47
【问题描述】:

我经历过许多类似的问题和 XSLT 教程,但我仍然无法弄清楚 XSLT 的工作原理。

下面是我要排序的 XML:-

<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
<file product="mxn" source-language="en">
<body>

<!-- Menu -->

    <msg-unit id="Menu.PerformTask">
        <msg>Perform Task</msg>
        <note>When selected performs a task.</note>
    </msg-unit>
    <msg-unit id="Menu.Add">
        <msg>Add New</msg>
        <note>When selected Adds a new row.</note>
    </msg-unit>

</body>
</file>
</xliff>

预期输出是:-

<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" version="1.1">
<file product="mxn" source-language="en">
<body>

<!-- Menu -->

    <msg-unit id="Menu.Add">
        <msg>Add New</msg>
        <note>When selected Adds a new row.</note>
    </msg-unit>
    <msg-unit id="Menu.PerformTask">
        <msg>Perform Task</msg>
        <note>When selected performs a task.</note>
    </msg-unit>

</body>
</file>
</xliff>

&lt;msg-unit&gt; 标签需要根据其id 属性的值进行排序。其他标签(如 cmets)应该在它们所在的位置。

我尝试了很多组合,但我对 XSLT 毫无头绪。以下是我最后一次尝试。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="/">
        <xsl:copy-of select="*">
            <xsl:apply-templates>
                <xsl:sort select="attribute(id)" />
            </xsl:apply-templates>
        </xsl:copy-of>
    </xsl:template>
</xsl:stylesheet>

这个只是吐出它得到的任何 XML,没有任何排序。

【问题讨论】:

    标签: xml xslt sorting


    【解决方案1】:

    编辑已更新 - 此模板将仅按 @idmsg-unit 元素进行排序,而不会干扰 xml 的其余部分。

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="2.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    >
        <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
        <xsl:strip-space elements="*"/>
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:choose>
                    <xsl:when test="*[local-name()='msg-unit']">
                        <xsl:apply-templates select="@* | node()">
                            <xsl:sort select="@id" />
                        </xsl:apply-templates>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="@* | node()" />
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

    • 谢谢它的工作。虽然&lt;xsl:output/&gt;中的indent="yes"似乎没有效果。也许&lt;xsl:strip-space elements="*" /&gt; 是压倒一切的。有没有办法在不丢失缩进的情况下删除空行?
    • @AppleGrew 很奇怪,在 MS 解析器中工作。可能尝试这些空白/漂亮的打印模板之一? stackoverflow.com/questions/1134318/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-30
    • 1970-01-01
    • 1970-01-01
    • 2011-07-16
    • 2017-09-02
    相关资源
    最近更新 更多