我尝试过使用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>
我需要的是对位于相同位置的Block
和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>
这更难,因为位置不是区域的属性,所以我基本上必须确定区域位置的值,然后抓住位于相同位置的House和Block,并将它们放在一起包围同样的<Area> </Area>
。
答案 0 :(得分:3)
对我来说,这似乎是一个相当标准的Muenchian分组问题,它们Area
将House
元素(不是Block
或Position
元素直接分组)。
<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
的直接子项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" />
(具有明确的优先级,因为没有这两个模板将具有相同的default priority 0.5)