Xml 使用XSLT1.0进行复杂分组

Xml 使用XSLT1.0进行复杂分组,xml,xslt-1.0,Xml,Xslt 1.0,我修改了数据文件并添加了分组列。否则,我想不出分组的逻辑 该数据包含有关集邮的信息 以下是示例XML: <?xml version="1.0" encoding="UTF-8"?> <stamps> <stamp> <Group>25</Group> <Scott>3133</Scott> <Title>32¢ Thornton Wilder</

我修改了数据文件并添加了分组列。否则,我想不出分组的逻辑

该数据包含有关集邮的信息

以下是示例XML:

<?xml version="1.0" encoding="UTF-8"?>
<stamps>        
<stamp>     
<Group>25</Group>       
<Scott>3133</Scott>     
<Title>32¢ Thornton Wilder</Title>      
<Series>Literary Arts</Series>      
</stamp>        
<stamp>     
<Group>26</Group>       
<Scott>3134</Scott>     
<Title>32¢ Charlie Chaplin</Title>      
</stamp>
<stamp>     
<Group>26</Group>       
<Scott>3135</Scott>     
<Title>32¢ Raoul Wallenberg</Title>     
</stamp>
<stamp>     
<Group>27</Group>       
<Scott>3136</Scott>     
<Title>Sheet of 15</Title>      
<Issue>The World of Dinosaurs</Issue>       
</stamp>        
<stamp>     
<Group>27</Group>       
<Scott>3136</Scott>     
<Minor>a</Minor>        
<Title>32¢ Ceratosaurus</Title>     
<Issue>The World of Dinosaurs</Issue>       
</stamp>        
<stamp>     
<Group>27</Group>       
<Scott>3136</Scott>     
<Minor>b</Minor>        
<Title>32¢ Camptosaurus</Title>     
<Issue>The World of Dinosaurs</Issue>       
</stamp>        
<stamp>     
<Group>27</Group>       
<Scott>3136</Scott>     
<Minor>c</Minor>        
<Title>32¢ Camarasaurus</Title>     
<Issue>The World of Dinosaurs</Issue>       
</stamp></stamps>

25
3133
32、桑顿怀尔德
文学艺术
26
3134
32、查理·卓别林
26
3135
32、拉乌尔·瓦伦伯格
27
3136
第页,共15页
恐龙世界
27
3136
A.
32¢角龙
恐龙世界
27
3136
B
32¢风龙
恐龙世界
27
3136
C
32¢卡马拉龙
恐龙世界
以下是我编写的XSLT:

<?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:key name="StampGroup" match="stamp" use="Group"/>
<xsl:key name="ScottGroup" match="stamp" use="concat(Group, '|', Scott)"/>

<xsl:template match="/*">
 <xsl:copy>
  <xsl:apply-templates select="stamp[generate-id() = generate-id(key('StampGroup', Group)[1])]" mode="StampGroup" />
 </xsl:copy>
 </xsl:template>

<xsl:template match="stamp" mode="StampGroup">
<StampGroup id="{Group}">        

<xsl:apply-templates select="key('StampGroup', Group)[generate-id() = generate-id(key('ScottGroup', concat(Group, '|', Scott))[1])]" mode="ScottGroup" />
</StampGroup>
</xsl:template>

<xsl:template match="stamp" mode="ScottGroup">
 <stamp>
  <Scott><xsl:value-of select="Scott"/></Scott>
  <Title><xsl:value-of select="Title"/></Title>
  <Minor><xsl:value-of select="Minor"/></Minor> 
 </stamp>
</xsl:template>

</xsl:stylesheet>

以下是生成的XML:

<?xml version="1.0" encoding="utf-8"?>
<stamps>
<StampGroup id="25">
  <stamp>
     <Scott>3133</Scott>
     <Title>32¢ Thornton Wilder</Title>
     <Minor/>
  </stamp>
</StampGroup>
<StampGroup id="26">
  <stamp>
     <Scott>3134</Scott>
     <Title>32¢ Charlie Chaplin</Title>
     <Minor/>
  </stamp>
  <stamp>
     <Scott>3135</Scott>
     <Title>32¢ Raoul Wallenberg</Title>
     <Minor/>
   </stamp>
  <stamp>
     <Scott>3136</Scott>
     <Title>Sheet of 15</Title>
     <Minor/>
  </stamp>
 </StampGroup>
</stamps>

3133
32、桑顿怀尔德
3134
32、查理·卓别林
3135
32、拉乌尔·瓦伦伯格
3136
第页,共15页
它基本上起作用了。它在吸引人群。它正在提取唯一的
项,但它没有提取
子项

我以前从未使用过这种类型的XSLT结构。您如何让它为每个项目重复项目

第27组有4个项目。它们都有相同的
编号,但不同的
字段

我需要创建第三个关键点吗

抱歉,忘记添加所需的结果:

<?xml version="1.0" encoding="utf-8"?>
<stamps>
<StampGroup id="25">
  <stamp>
     <Scott>3133</Scott>
     <Title>32¢ Thornton Wilder</Title>
     <Minor/>
  </stamp>
</StampGroup>
<StampGroup id="26">
  <stamp>
     <Scott>3134</Scott>
     <Title>32¢ Charlie Chaplin</Title>
     <Minor/>
  </stamp>
  <stamp>
     <Scott>3135</Scott>
     <Title>32¢ Raoul Wallenberg</Title>
     <Minor/>
  </stamp>
</StampGroup>
<StampGroup id="27">
  <stamp>
     <Scott>3136</Scott>
     <Title>Sheet of 15</Title>
     <Minor/>
  </stamp>
  <stamp>
     <Scott>3136</Scott>
     <Title>32¢ Ceratosaurus</Title>
     <Minor>a</Minor>       
  </stamp>
  <stamp>
     <Scott>3136</Scott>
     <Title>32¢ Camptosaurus</Title>    
     <Minor>b</Minor>       
  </stamp>
  <stamp>
     <Scott>3136</Scott>
     <Title>32¢ Camarasaurus</Title>
     <Minor>c</Minor>       
  </stamp>
 </StampGroup>
</stamps>

3133
32、桑顿怀尔德
3134
32、查理·卓别林
3135
32、拉乌尔·瓦伦伯格
3136
第页,共15页
3136
32¢角龙
A.
3136
32¢风龙
B
3136
32¢卡马拉龙
C

您的问题很有趣。基本订单为ItemNo,更改时带有分组标题,但如果是系列或发行的组,则应在不更改ItemNo订单的情况下有另一个分组标题。我了解了以下内容,并使用带有背景色的html表格作为分组标题,以便于概览。我没有完全理解预期的输出,我不是邮票专家。剧本应该会告诉你如何解决这个问题

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="ItemNo" match="stamp" use="ItemNo" />
    <xsl:key name="Series" match="stamp" use="Series" />
    <xsl:key name="Issue" match="stamp" use="Issue" />
    <xsl:template match="/">
        <table border="1">
            <xsl:apply-templates select="stamps/stamp[generate-id(.)=generate-id(key('ItemNo',ItemNo)[1])]" mode="groupItem">
                <xsl:sort select="ItemNo"/>
            </xsl:apply-templates>
        </table>
    </xsl:template>
    <xsl:template match="stamp" mode="groupItem">
        <xsl:variable name="varItemNo" select="ItemNo"/>
        <xsl:apply-templates select="../stamp[ItemNo=$varItemNo][generate-id(.)=generate-id(key('Series',Series)[1])]" mode="groupSeries">
            <xsl:sort select="ItemNo"/>
        </xsl:apply-templates>
        <xsl:apply-templates select="../stamp[ItemNo=$varItemNo][generate-id(.)=generate-id(key('Issue',Issue)[1])]" mode="groupIssue">
            <xsl:sort select="Issue"/>
        </xsl:apply-templates>
        <tr style="background-color:yellow">
            <td><xsl:value-of select="ItemNo"/></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <xsl:apply-templates select="../stamp[ItemNo=$varItemNo]">
            <xsl:sort select="Series"/>
            <xsl:sort select="Issue"/>
            <xsl:sort select="Minor"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="stamp" mode="groupSeries">
        <tr style="background-color:gold">
            <td></td>
            <td></td>
            <td><xsl:value-of select="Series"/></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </xsl:template>
    <xsl:template match="stamp" mode="groupIssue">
        <tr style="background-color:tan">
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td><xsl:value-of select="Issue"/></td>
            <td></td>
        </tr>
    </xsl:template>
    <xsl:template match="stamp">
        <tr>
            <td><xsl:value-of select="ItemNo"/></td>
            <td><xsl:value-of select="Date"/></td>
            <td><xsl:value-of select="Series"/></td>
            <td><xsl:value-of select="Name"/></td>
            <td><xsl:value-of select="Issue"/></td>
            <td><xsl:value-of select="Minor"/></td>
        </tr>
    </xsl:template>
</xsl:stylesheet>


。。。是的,html是不完整的,如果您想在每个
组中只包含唯一的
Scott
值,并且在每个
Scott
子组中只包含唯一的
Minor
值,那么是的,您需要三个键

如果要分组的值对于每个父组不是唯一的,则必须连接键,以便将键缩小到仅来自当前父组的匹配项

XSLT1.0

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

<xsl:key name="stamp-by-group" match="stamp" use="Group" />
<xsl:key name="stamp-by-scott" match="stamp" use="concat(Group, '|', Scott)" />
<xsl:key name="stamp-by-minor" match="stamp" use="concat(Group, '|', Scott, '|', Minor)" />

<xsl:template match="/stamps">
    <xsl:copy>
        <xsl:for-each select="stamp[count(. | key('stamp-by-group', Group)[1]) = 1]">
            <StampGroup id="{Group}">
                <xsl:for-each select="key('stamp-by-group', Group)[count(. | key('stamp-by-scott', concat(Group, '|', Scott))[1]) = 1]">
                    <xsl:apply-templates select="key('stamp-by-scott', concat(Group, '|', Scott))[count(. | key('stamp-by-minor', concat(Group, '|', Scott, '|', Minor))[1]) = 1]"/>
                </xsl:for-each>
            </StampGroup>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

<xsl:template match="stamp">
    <xsl:copy>
        <xsl:copy-of select="Scott | Title"/>
        <Minor><xsl:value-of select="Minor" /></Minor>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

您可以发布您尝试过的XSLT吗?另外,您可以发布一个小样本XML和预期的输出吗?我的XSLT无法正确分组数据。把它贴出来会有任何帮助。我会尽快整理出预期的输出并发布。Thanks对原始数据进行了修改,并添加了一个新的XSLT,该XSLT大部分工作正常。我需要帮助,以获得小邮票项目显示。我想我需要一个for-each语句,但我不知道如何将它添加到这种类型的XSL中。感谢数据文件已更改。我可以在原始数据上尝试您的解决方案,但原始数据有问题。它没有防弹逻辑。我注意到序列和问题字段在整个数据集中不是唯一的。因此,无法确保每个系列名称都有一个唯一的键。另一个更严重的问题是,一些邮票组合包括多个系列和发行组合。这都是武断的。因此,我回到数据中,添加了一个独特的字段来分组。这非常有效。我之前试过同样的第三把钥匙,但没用。我想我错过了每句话的第二句。Thanks@JimMaivald想一想,如果你没有为第二组创建任何内容,你可以跳过第二个
xsl:for each
语句-参见我文章的编辑。实际上,我刚刚发布了一个关于这个概念的第二个问题。一些Scott编号被多次使用,标题不同,但没有次要变体。
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="stamp-by-group" match="stamp" use="Group" />
<xsl:key name="stamp-by-minor" match="stamp" use="concat(Group, '|', Scott, '|', Minor)" />

<xsl:template match="/stamps">
    <xsl:copy>
        <xsl:for-each select="stamp[count(. | key('stamp-by-group', Group)[1]) = 1]">
            <StampGroup id="{Group}">
                <xsl:apply-templates select="key('stamp-by-group', Group)[count(. | key('stamp-by-minor', concat(Group, '|', Scott, '|', Minor))[1]) = 1]"/>
            </StampGroup>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

<xsl:template match="stamp">
    <xsl:copy>
        <xsl:copy-of select="Scott | Title"/>
        <Minor><xsl:value-of select="Minor" /></Minor>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>