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

基于XSLT实现XML元素及属性的字母序排序需求

XML元素与属性按字母排序的XSLT实现

需求说明

我需要将XML文件中的元素以及元素内的属性都按字母顺序排序,目前刚接触XSLT,尝试写了模板但没达到预期效果。

源XML(source.xml)

<?xml version="1.0" encoding="UTF-8"?>
<wgtPage projectType="project" rev="1">
   <object staticFile="opt/IMAGE.png"
           id="ZZZZZZZZZ"
           staticOptEnable="true"
           dataWndSize="0,70"
           downloadPrepDone="true"
           usedFonts="Siemens AD Sans"
           pageSize="1920,1080"
           class="PageWgt"
           pageName="PAGENAME"
           templateFile="PAEGEFILE.XML">
      <wgtStyle width="1920"
                height="1080"
                ver="040500548"
                fitToSize="1"
                x="0"
                y="0"
                v="04.05.00.548"/>
      <object mgrType="Page"
              id="_PageMLTextMgrWgt"
              mlFileName=""
              class="PageMLTextMgrWgt">
         <wgtStyle width="0" height="0" x="0" y="0"/>
         <langs curLangId="L1" defLangId="L1">
            <lang name="ITA"
                  defaultFont="ARIAL"
                  keypads=";;;"
                  writingsystem="Any"
                  langId="L1"
                  langCode="it"
                  removable="false"/>
         </langs>
         <MLTexts>
            <MLText id="0" L1="A"/>
            <MLText id="1" L1="E "/>
            <MLText id="36" L1="D"/>
            <MLText id="37" L1="B"/>
         </MLTexts>
      </object>
      <object id="label11" class="LabelWgt">
         <wgtStyle wrapping="true"
                   width="247"
                   height="29"
                   font-bold="true"
                   keypad-type="None"
                   vert-align="middle"
                   font-sizepx="21"
                   font-color="rgb(255,215,0)"
                   font-size="16"
                   marker="true"
                   x="9"
                   y="28"
                   forcePaint="1"
                   cx="123.50"
                   cy="13.74"
                   font-family="Sans"/>
         <links>
            <lang textid="0" class="MLTextLink"/>
         </links>
      </object>
      <links>
         <lang textid="36" class="MLTextLink"/>
      </links>
   </object>
   <object id="GroupWgt5.label1" class="LabelWgt">
      <wgtStyle y="877"
                font-size="22"
                height="76"
                frameSize="0"
                vert-align="middle"
                font-family="ARIAL"
                x="1122"
                alignment="center"
                forcePaint="25"
                wgtStaticOpt="dynamic"
                frameColor="rgb(200,200,200)"
                font-color="rgb(255,255,255)"
                cy="34.20"
                frameFill="rgb(102,102,102)"
                frame="true"
                keypad-type="None"
                font-sizepx="29"
                wrapping="true"
                width="210"
                cx="107.56"/>
      <dataLinks>
         <dataLink tag="THISISATAG"
                   tagType="boolean"
                   widgetType="Project"
                   attribute="frameFill"
                   sourceType="Tag"
                   tagIndex="-1"
                   dataSource="_TagMgr"
                   class="TagMgrWgt"
                   readWrite="R">
            <xForms>
               <xForm name="ColorPaletteCustom"
                      ColorPaletteCustom="#707070;#009942"
                      class="ColorPaletteCustomXForm">
                  <value i="0">0</value>
                  <value i="1">1</value>
               </xForm>
            </xForms>
         </dataLink>
      </dataLinks>
      <links>
         <lang textid="37" class="MLTextLink"/>
      </links>
   </object>
   <object id="MAINOBJ@$GroupSubscrWgt@$0" class="GroupSubscribeWgt">
      <wgtStyle width="0" height="0" x="0" y="0"/>
   </object>
</wgtPage>

我尝试的XSLT模板

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

    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
    <xsl:strip-space elements="*"/>

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

</xsl:stylesheet>

修正后的XSLT实现

要同时实现属性按字母排序和同级元素按字母排序,需要分开处理属性和元素:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <!-- 输出格式化的XML,保留声明 -->
    <xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="UTF-8"/>
    <!-- 去除多余空白 -->
    <xsl:strip-space elements="*"/>

    <!-- 匹配所有节点和属性的基础模板 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <!-- 先处理属性:按属性名称字母排序 -->
            <xsl:apply-templates select="@*">
                <xsl:sort select="name()" data-type="text" order="ascending"/>
            </xsl:apply-templates>
            <!-- 再处理子元素:按元素名称字母排序;同类型元素按id属性排序 -->
            <xsl:apply-templates select="node()">
                <xsl:sort select="name()" data-type="text" order="ascending"/>
                <xsl:sort select="@id" data-type="text" order="ascending"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

关键说明

  1. 属性排序:对所有属性应用模板时,通过<xsl:sort select="name()"/>按属性名称的字母顺序排列。
  2. 元素排序:对子元素先按元素名称排序;如果是同类型元素(比如多个<MLText>),再按id属性排序,确保同类型元素内部也有序。
  3. 原模板问题:仅按@id排序,未处理属性排序逻辑,且对无id属性的元素排序规则不完整,导致部分内容未按预期排序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:44:56