【问题标题】:How to sort a subelement of XML with XSLT如何使用 XSLT 对 XML 的子元素进行排序
【发布时间】:2010-10-09 00:59:23
【问题描述】:

我有一个输入 XML 文件,我需要将它 1:1 复制到输出中,除了一个包含需要排序的子项的子元素。

<?xml version="1.0"?>
<top>
  <elementA />
  <elementB />
  <contents>
      <contentitem>
          <id>3</id>
          <moretags1 />
          <moretags2 />
      </contentitem>
      <contentitem>
          <id>2</id>
          <moretags1 />
          <moretags2 />
      </contentitem>
      <contentitem>
          <id>1</id>
          <moretags1 />
          <moretags2 />
      </contentitem>
  </contents>
</top>

我想要一个 XSL 转换,它将“contentitem”元素按其“id”元素排序。 所有其他标签,包括嵌套标签,都必须逐字复制。我已经尝试过使用 xsl:copy,但要么我得到了双重内容,要么结果丢失了。

【问题讨论】:

    标签: xml xslt sorting


    【解决方案1】:

    将 xsl:sort 与 xsl:for-each 或 xsl:apply-templates 一起使用

    类似

    <xsl:template match='/top/contents'>
      <xsl:apply-templates select='contentitem'>
        <xsl:sort select='id' data-type='number'/>
      </xsl:apply-templates>
    </xsl:template>
    

    多个 xsl:sort 元素可用于多个排序键。

    【讨论】:

    • 这不是一个完整的解决方案,而是专注于如何排序。
    【解决方案2】:

    怎么样:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output method="xml" indent="yes"/>
      <xsl:template match="@* | node()">
        <xsl:copy>
          <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
      </xsl:template>
      <xsl:template match="/top/contents">
        <contents>
          <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="contentitem">
              <xsl:sort data-type="number" select="id"/>
            </xsl:apply-templates>
          </xsl:copy>
        </contents>
      </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

      【解决方案3】:

      Mark Gravell 的解决方案几乎是正确的——有一个小问题,即创建了两个嵌套的 &lt;contents&gt; 元素。 所有提供答案的人请注意:请测试您的解决方案!

      这是一个正确的解决方案。这种转变:

      <xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       <xsl:output omit-xml-declaration="yes" indent="yes"/>
      <!--                                                --> 
       <xsl:strip-space elements="*"/>
      <!--                                                --> 
        <xsl:template match="node()|@*">
          <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
          </xsl:copy>
        </xsl:template>
      <!--                                                --> 
        <xsl:template match="contents">
          <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="contentitem">
              <xsl:sort select="id" data-type="number"/>
            </xsl:apply-templates>
          </xsl:copy>
        </xsl:template>
      </xsl:stylesheet>
      

      应用于原始提供的 XML 文档时:

      <top>
          <elementA />
          <elementB />
          <contents>
              <contentitem>
                  <id>3</id>
                  <moretags1 />
                  <moretags2 />
              </contentitem>
              <contentitem>
                  <id>2</id>
                  <moretags1 />
                  <moretags2 />
              </contentitem>
              <contentitem>
                  <id>1</id>
                  <moretags1 />
                  <moretags2 />
              </contentitem>
          </contents>
      </top>
      

      产生想要的正确结果:

      <top>
         <elementA/>
         <elementB/>
         <contents>
            <contentitem>
               <id>1</id>
               <moretags1/>
               <moretags2/>
            </contentitem>
            <contentitem>
               <id>2</id>
               <moretags1/>
               <moretags2/>
            </contentitem>
            <contentitem>
               <id>3</id>
               <moretags1/>
               <moretags2/>
            </contentitem>
         </contents>
      </top>
      

      请注意以下事项:

      1. 使用identity rule复制所有节点不做改动。

      2. 如何使用与 contents 元素匹配的特定模板覆盖身份模板

      3. &lt;xsl:sort&gt; 指令的使用以特定顺序呈现应用模板的结果,可能与选择处理的节点的文档顺序不同。 p>

      【讨论】:

        猜你喜欢
        • 2019-05-08
        • 2021-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-17
        • 1970-01-01
        • 2021-08-13
        相关资源
        最近更新 更多