You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSLT实现XML对象数字排序并保留注释的技术求助

解决XML中object元素数字排序并保留注释的XSLT方案

我用工具将游戏数据转换为XML时,工具存在缺陷:父级object元素按字母顺序而非数字顺序排列,示例XML如下:

<container format="RTPC" endian="Little">
    <object>
        <object name="root">
            <object name="0"><!-- disables input -->
                <value name="_class" type="string">CInputActionOverride</value>
                <value name="_class_hash" type="int">-1833934533</value>
                <value name="_object_id" type="objectid">26D7913A,0</value>
                <value name="action_list" type="string">Accelerate</value><!-- action name -->
                <value name="activate_event" type="vec_events">death_run_play_cutscene,0x0</value>
            </object>
            <object name="1">
                <value name="_class" type="string">CGameObjectList</value>
                <value name="_class_hash" type="int">-1531974803</value>
                <value name="_object_id" type="objectid">C51129BC,0</value><!-- spawn list ref -->
                <value name="name" type="string">SpawnedVehicleList</value>
                <value name="tags" type="vec_int"/>
            </object>
            <object name="10">
                <value name="_class" type="string">CNavMeshDynamicObstacle</value>
                <value name="_class_hash" type="int">838607288</value>
                <value name="_object_id" type="objectid">F96135EC,0</value>
                <value name="disable_event" type="vec_events"/>
                <value name="enable_event" type="vec_events"/>
                <value name="enabled_from_start" type="int">1</value>
            </object>
            <object name="100">
                <value name="_class" type="string">SAnimationLayerInfo</value>
                <value name="_class_hash" type="int">-786417417</value>
                <value name="_object_id" type="objectid">B2B5BF10,0</value>
                <value name="file" type="string">animations/characters/light_facelayer.al</value><!-- anim path -->
                <value name="layer_index" type="int">1</value>
                <value name="layer_name" type="string">Face</value>
                <value name="name" type="string">AnimationLayerInfoFace</value>
            </object>
            <object name="102">
                <value name="_class" type="string">CSpawnReferencePosition</value>
                <value name="_class_hash" type="int">-1429677905</value>
                <value name="_object_id" type="objectid">1958DDF6,0</value>
                <value name="keep_orientation" type="int">1</value>
                <value name="name" type="string">CSpawnReferencePosition</value>
                <value name="no_create_on_load" type="int">1</value>
                <value name="tags" type="vec_int"/>
            </object>
        </object>
    </object>
</container>

我尝试用以下XSLT模板解决排序问题,但它会丢失所有注释:

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

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

    <xsl:template match="object">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="*">
                <xsl:sort select="@name" data-type="number" order="ascending"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

修改后的XSLT方案

以下模板可实现object元素按数字排序,同时完整保留所有注释:

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

    <!-- 身份模板:复制所有节点、属性,包括注释和文本节点 -->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- 仅对包含子object元素的父object节点进行排序处理 -->
    <xsl:template match="object[object/@name]">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <!-- 先输出非object类型的子节点(注释、文本等),保留原始位置 -->
            <xsl:apply-templates select="node()[not(self::object)]"/>
            <!-- 对object子节点按name属性进行数字升序排序 -->
            <xsl:apply-templates select="object">
                <xsl:sort select="@name" data-type="number" order="ascending"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

方案说明

  • 原模板丢失注释的原因:仅处理object的子元素(*),忽略了注释、文本等非元素节点,且XSLT默认不保留注释。
  • 修改点:
    1. 保留身份模板,确保所有节点(包括注释、属性、文本)都被复制。
    2. 新增针对性模板,只对包含数字命名子object的父object节点做排序处理。
    3. 先处理非object子节点(如注释),再对object子节点按name属性做数字排序,既实现排序需求,又完整保留所有注释内容。

内容的提问来源于stack exchange,提问作者DMGT4

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 04:49:51