3

我已经有一个 XSL,它根据属性值 @id 或 @category 对整个文档进行排序。现在我想通过定义永远不应该排序的节点来增强它。

这是一个示例 XML:

<root>
    [several levels of xml open]

    <elemetsToBeSorted>
        <sortMe id="8" />
        <sortMe id="2" />
        <sortMe id="4" />
    </elemetsToBeSorted>

    <elemetsNOTToBeSorted>
        <dontSortMe id="5" />
        <dontSortMe id="3" />
        <dontSortMe id="2" />
    </elemetsNOTToBeSorted>

    [several levels of xml closing]
</root>

这是我的 XSL:

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

<xsl:output method="xml" indent="yes" />

<!-- Sort all Elements after their id or category -->
<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()">
            <xsl:sort select="@id" />
            <xsl:sort select="@category" />
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>


<!-- Next two templates clean up formatting after sorting -->
<xsl:template match="text()[not(string-length(normalize-space()))]" />

<xsl:template match="text()[string-length(normalize-space()) > 0]">
    <xsl:value-of select="translate(.,'&#xA;&#xD;', '  ')" />
</xsl:template>

预期输出:

<root>
    [several levels of xml open]

    <elemetsToBeSorted>
        <sortMe id="2" />
        <sortMe id="4" />
        <sortMe id="8" />
    </elemetsToBeSorted>

    <elemetsNOTToBeSorted>
        <dontSortMe id="5" />
        <dontSortMe id="3" />
        <dontSortMe id="2" />
    </elemetsNOTToBeSorted>

    [several levels of xml closing]
</root>

我怎样才能实现我的 XSL 忽略“elementsNOTToBeSorted”?

编辑:我有数百个元素应该排序,但只有少数元素(及其子元素)不应该排序。所以逻辑就像“排序所有,除了a和b”

4

2 回答 2

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

<!-- all elements except a few sort their children -->
<xsl:template match="*[not(self::elemetsNOTToBeSorted | self::otherElemetsNOTToBeSorted)]">
    <xsl:copy>
        <xsl:apply-templates select="@*" />
        <xsl:apply-templates>
            <xsl:sort select="@id" />
            <xsl:sort select="@category" />
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

<!-- ... -->

请注意,匹配表达式特异性在这里起作用。更具体的匹配表达式确定将运行哪个模板:

  • node()不那么具体*,因此元素节点将由<xsl:template match="*">
  • 元素匹配self::elemetsNOTToBeSorted | self::otherElemetsNOTToBeSorted将由标识模板处理。
于 2012-10-11T08:44:32.237 回答
0

添加这一行应该忽略 elementsNOTToBeSorted 的所有后代元素:

<xsl:template match="elemetsNOTToBeSorted" />

如果您希望这些元素仍然存在于输出文档中,您可以复制它们而不是抑制:

<xsl:template match="elemetsNOTToBeSorted">
    <xsl:copy-of select="." />
</xsl:template>
于 2012-10-10T20:47:45.353 回答