2

我尝试过使用 XSLT 1.0 对 XML 进行简单的分组,并且效果很好,但是在这里我遇到了一些更复杂且实际上不同的情况。所以XML结构基本上是这样的:

<Main>
 <TB>
    --> some elements and stuff - not relevant
   <City>
     <Area>
       <Position>5</Position>
       <House>

       --> some elements and stuff

       </House>
     </Area>
     <Area>
       <Position>5</Position>
       <Block>

       --> some elements and stuff

       </Block>
     </Area>
     <Area>
       <Position>6</Position>
       <House>

       --> some elements and stuff

       </House>
     </Area>
     <Area>
       <Position>6</Position>
       <Block>

       --> some elements and stuff

       </Block>
     </Area>
   </City>
   <City>

   --> same structure but with several repetitions of Position 7 and 8.

   </City>
 </TB>
</Main>

我需要的是对同一位置下的Blocks 和s 进行分组,并删除重复的位置编号。House例如它会变成这样:

   <City>
     <Area>
       <Position>5</Position>
       <House>

       --> some elements and stuff

       </House>
       <Block>

       --> some elements and stuff

       </Block>
     </Area>
     <Area>
       <Position>6</Position>
       <House>

       --> some elements and stuff

       </House>
       <Block>

       --> some elements and stuff

       </Block>
     </Area>
   </City>
   <City>

   --> same structure for Position 7 and 8.

   </City>

比较难,因为Position不是Area的属性,所以我基本上要识别Area的Position的值,然后把同一个Position下的House和Block抓起来,放在同一个包围下<Area> </Area>

4

1 回答 1

3

对我来说,这看起来像是一个相当标准的AreaMuenchian分组问题,通过它们的.HouseBlockPosition

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

  <xsl:key name="areaByPosition" match="Area" use="Position" />

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

  <!-- for the first Area in each Position -->
  <xsl:template match="Area[generate-id() =
                            generate-id(key('areaByPosition', Position)[1])]">
    <Area>
      <!-- copy in the Position element once only -->
      <xsl:apply-templates select="Position" />
      <!-- copy in all sub-elements except Position from all matching Areas -->
      <xsl:apply-templates select="
            key('areaByPosition', Position)/*[not(self::Position)]" />
    </Area>
  </xsl:template>

  <!-- ignore all other Area elements -->
  <xsl:template match="Area" />
</xsl:stylesheet>

这假设在文档的其他地方没有命名其他元素Area,如果可以命名任何“一些元素和东西”,Area那么您需要更具体一些,例如将分组限制Area为 a 的直接子元素City

<xsl:key name="areaByPosition" match="City/Area" use="Position" />

<xsl:template match="City/Area[generate-id() =
                               generate-id(key('areaByPosition', Position)[1])]"
              priority="2">
  ...
</xsl:template>

<xsl:template match="City/Area" priority="1" />

(有明确的优先级,因为没有这两个模板将具有相同的默认优先级0.5)

于 2013-05-20T10:46:22.250 回答