XSLT 1.0 在同一级别上转换一些节点,而其他节点则保持不变

XSLT 1.0 transform some nodes on the same level, leave others intact

我面临的问题是,如何 select 一些与其他不同节点处于同一级别的节点,并只对它们进行排序,而使其他节点保持不变。我试图通过使用模板匹配来匹配它们,但无法弄清楚如何在没有 selecting 任何后代的情况下对它们进行排序(for-each 和 apply-templates 需要 select.. .)

我有以下XML

<RootNode>
    <actionOverrides>
        <type>Default</type>
    </actionOverrides>
    <actionOverrides>
        <formFactor>Small</formFactor>
        <type>Page</type>
    </actionOverrides>
    <actionOverrides>
        <formFactor>Large</formFactor>
        <type>Page</type>
    </actionOverrides>
    <actionOverrides>
        <actionName>View</actionName>
        <type>Default</type>
    </actionOverrides>
    <deprecated>false</deprecated>
    <somethingElse>false</somethingElse>
</RootNode>

我需要对某些子节点进行排序(基于子节点的子节点值)--> 对 actionOverrides 进行排序,其中类型 = 'Page',按 formFactor

排序
<RootNode>
    <actionOverrides>
        <type>Default</type>
    </actionOverrides>
    <actionOverrides>
        <formFactor>Large</formFactor>
        <type>Page</type>
    </actionOverrides>
    <actionOverrides>
        <formFactor>Small</formFactor>
        <type>Page</type>
    </actionOverrides>
    <actionOverrides>
        <actionName>View</actionName>
        <type>Default</type>
    </actionOverrides>
    <deprecated>false</deprecated>
    <somethingElse>false</somethingElse>
</RootNode>

我试过类似的东西,但这给了我重复项。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://soap.sforce.com/2006/04/metadata">
    <xsl:output method="xml" indent="yes"/>
    <!-- XSLT identity transformation -->
    <xsl:template match="@*|node()" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="/RootNode/actionOverrides[type='Page']">
        <xsl:for-each select="../actionOverrides[type='Page']">
            <xsl:sort select="formFactor" order="ascending"/>
            <xsl:copy-of select="."/>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

这是您可以查看的一种方式:

XSLT 1.0

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

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

<xsl:template match="/RootNode">
    <xsl:copy>
        <xsl:apply-templates select="actionOverrides[type='Page'][1]/preceding-sibling::*"/>
        <xsl:apply-templates select="actionOverrides[type='Page']">
            <xsl:sort select="formFactor"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="actionOverrides[type='Page'][last()]/following-sibling::*"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>