使用XSLT显示具有相同ID的多个项目组

时间:2015-06-04 19:43:29

标签: xml xslt

以下解决方案几近完美。但我发现有些物品具有相同的斯科特数字,但没有小字段。

我需要显示具有相同Scott#的项目,这些项目具有不同的<Title>字段和数据。

例如,Scott#3090&amp; Sons中有两枚邮票。 3152但结果中只显示一个。 XSLT必须重复使用相同Scott#的邮票,但不具有次要变体

这是当前的XSLT:

 <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}">
 <GroupTitle><xsl:choose><xsl:when test="Series"><Series><xsl:value-of select="Series" /></Series></xsl:when>
    <xsl:otherwise>
     <xsl:choose>
        <xsl:when test="Issue"><Issue><xsl:value-of select="Issue" /></Issue>
        </xsl:when>
            <xsl:otherwise>
            <empty />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:otherwise>
 </xsl:choose></GroupTitle>

 <xsl:for-each select="key('stamp-by-group', Group)[count(. | key('stamp-by-scott', concat(Group, '|', Scott))[1]) = 1]">

 <stampvariants>   
 <xsl:apply-templates select="key('stamp-by-scott', concat(Group, '|', Scott))[count(. | key('stamp-by-minor', concat(Group, '|', Scott, '|', Minor))[1]) = 1]"/>
 </stampvariants>\
 </xsl:for-each>

 </StampGroup>
    </xsl:for-each>
 </xsl:copy>
 </xsl:template>

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

 </xsl:template>

 </xsl:stylesheet>

以下是XML示例:

<?xml version="1.0" encoding="UTF-8"?>
<stamps>        
<stamp>
<Group>1</Group>
<Scott>3090</Scott>
<Title>32¢ Rural Free Delivery</Title>
</stamp>
<stamp>
<Group>1</Group>
<Scott>3090</Scott>
<Title>Pane of 20</Title>
</stamp>
<stamp>
<Group>2</Group>
<Scott>3091</Scott>
<Title>32¢ Robert E. Lee</Title>
<Issue>Riverboats</Issue>
</stamp>
<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>
<stamp>
<Group>35</Group>
<Scott>3152</Scott>
<Title>32¢ Humphrey Bogart</Title>
<Series>Legends of Hollywood</Series>
</stamp>
<stamp>
<Group>35</Group>
<Scott/> 
<Title>Pane of 20</Title>
</stamp>
</stamps>

请注意,第1组和第35组具有相同的Scott #s但没有Minor变体。变体的标题不同。 XSLT需要遍历所有Scott #s和Minor变体。

这是目前的结果:

 <?xml version="1.0" encoding="UTF-8"?>
 <stamps>
 <StampGroup id="1">
  <GroupTitle>
     <empty/>
  </GroupTitle>
  <stampvariants>
     <stamp>
        <Scott>3090</Scott>
        <Minor/>
        <Title>32¢ Rural Free Delivery</Title>
     </stamp>
  </stampvariants>
 </StampGroup>
 <StampGroup id="2">
  <GroupTitle>
     <Issue>Riverboats</Issue>
  </GroupTitle>
  <stampvariants>
     <stamp>
        <Scott>3091</Scott>
        <Minor/>
        <Title>32¢ Robert E. Lee</Title>
     </stamp>
  </stampvariants>
 </StampGroup>
 <StampGroup id="25">
  <GroupTitle>
     <Series>Literary Arts</Series>
  </GroupTitle>
  <stampvariants>
     <stamp>
        <Scott>3133</Scott>
        <Minor/>
        <Title>32¢ Thornton Wilder</Title>
     </stamp>
  </stampvariants>
 </StampGroup>
 <StampGroup id="26">
  <GroupTitle>
     <empty/>
  </GroupTitle>
  <stampvariants>
     <stamp>
        <Scott>3134</Scott>
        <Minor/>
        <Title>32¢ Charlie Chaplin</Title>
     </stamp>
  </stampvariants>
 <stampvariants>
     <stamp>
        <Scott>3135</Scott>
        <Minor/>
        <Title>32¢ Raoul Wallenberg</Title>
     </stamp>
  </stampvariants>
 </StampGroup>
 <StampGroup id="27">
  <GroupTitle>
     <Issue>The World of Dinosaurs</Issue>
  </GroupTitle>
  <stampvariants>
     <stamp>
        <Scott>3136</Scott>
        <Minor/>
        <Title>Sheet of 15</Title>
     </stamp>
     <stamp>
        <Scott>3136</Scott>
        <Minor>a</Minor>
        <Title>32¢ Ceratosaurus</Title>
     </stamp>
     <stamp>
        <Scott>3136</Scott>
        <Minor>b</Minor>
        <Title>32¢ Camptosaurus</Title>
     </stamp>
     <stamp>
        <Scott>3136</Scott>
        <Minor>c</Minor>
        <Title>32¢ Camarasaurus</Title>
     </stamp>
  </stampvariants>
</StampGroup>
<StampGroup id="35">
  <GroupTitle>
     <Series>Legends of Hollywood</Series>
  </GroupTitle>
  <stampvariants>
     <stamp>
        <Scott>3152</Scott>
        <Minor/>
        <Title>32¢ Humphrey Bogart</Title>
     </stamp>
  </stampvariants>
 </StampGroup>
 </stamps>

这是理想的结果:

  <?xml version="1.0" encoding="UTF-8"?>
 <stamps>
 <StampGroup id="1">
  <GroupTitle>
     <empty/>
  </GroupTitle>
  <stampvariants>
     <stamp>
        <Scott>3090</Scott>
        <Minor/>
        <Title>32¢ Rural Free Delivery</Title>
     </stamp>
     <stamp>
        <Scott>3090</Scott>
        <Minor/>
        <Title>Pane of 20</Title>
     </stamp>
  </stampvariants>
 </StampGroup>

 <StampGroup id="2">
  <GroupTitle>
     <Issue>Riverboats</Issue>
  </GroupTitle>
  <stampvariants>
     <stamp>
        <Scott>3091</Scott>
        <Minor/>
        <Title>32¢ Robert E. Lee</Title>
     </stamp>
  </stampvariants>
 </StampGroup>

 <StampGroup id="25">
  <GroupTitle>
     <Series>Literary Arts</Series>
  </GroupTitle>
  <stampvariants>
     <stamp>
        <Scott>3133</Scott>
        <Minor/>
        <Title>32¢ Thornton Wilder</Title>
     </stamp>
  </stampvariants>
 </StampGroup>

 <StampGroup id="26">
  <GroupTitle>
     <empty/>
  </GroupTitle>
  <stampvariants>
     <stamp>
        <Scott>3134</Scott>
        <Minor/>
        <Title>32¢ Charlie Chaplin</Title>
     </stamp>
  </stampvariants>
 <stampvariants>
     <stamp>
        <Scott>3135</Scott>
        <Minor/>
        <Title>32¢ Raoul Wallenberg</Title>
     </stamp>
  </stampvariants>
 </StampGroup>

 <StampGroup id="27">
  <GroupTitle>
     <Issue>The World of Dinosaurs</Issue>
  </GroupTitle>
  <stampvariants>
     <stamp>
        <Scott>3136</Scott>
        <Minor/>
        <Title>Sheet of 15</Title>
     </stamp>
     <stamp>
        <Scott>3136</Scott>
        <Minor>a</Minor>
        <Title>32¢ Ceratosaurus</Title>
     </stamp>
     <stamp>
        <Scott>3136</Scott>
        <Minor>b</Minor>
        <Title>32¢ Camptosaurus</Title>
     </stamp>
     <stamp>
        <Scott>3136</Scott>
        <Minor>c</Minor>
        <Title>32¢ Camarasaurus</Title>
     </stamp>
  </stampvariants>
</StampGroup>

<StampGroup id="35">
  <GroupTitle>
     <Series>Legends of Hollywood</Series>
  </GroupTitle>
  <stampvariants>
     <stamp>
        <Scott>3152</Scott>
        <Minor/>
        <Title>32¢ Humphrey Bogart</Title>
     </stamp>
     <stamp>
        <Scott>3152</Scott>
        <Minor/>
        <Title>Pane of 20</Title>
     </stamp>
  </stampvariants>
 </StampGroup>
 </stamps>

1 个答案:

答案 0 :(得分:0)

AFAICT,你想做类似的事情:

XSLT 1.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}">
                <GroupTitle><!-- immaterial for this answer --></GroupTitle>
                <xsl:for-each select="key('stamp-by-group', Group)[count(. | key('stamp-by-scott', concat(Group, '|', Scott))[1]) = 1]">
                    <stampvariants>   
                        <xsl:for-each select="key('stamp-by-scott', concat(Group, '|', Scott))[count(. | key('stamp-by-minor', concat(Group, '|', Scott, '|', Minor))[1]) = 1]">
                            <xsl:choose>
                                <xsl:when test="not(Minor)">
                                    <xsl:apply-templates select="key('stamp-by-minor', concat(Group, '|', Scott, '|', Minor))"/>
                                </xsl:when>
                                <xsl:otherwise>
                                    <xsl:apply-templates select="."/>
                                </xsl:otherwise>
                            </xsl:choose>
                        </xsl:for-each>
                    </stampvariants>
                </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>

如果重写为:

,此时可能更易于管理
<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:apply-templates select="stamp[count(. | key('stamp-by-group', Group)[1]) = 1]" mode="group"/>
    </xsl:copy>
</xsl:template>     

<xsl:template match="stamp" mode="group">
    <StampGroup id="{Group}">
        <GroupTitle><!-- immaterial for this answer --></GroupTitle>
        <xsl:apply-templates select="key('stamp-by-group', Group)[count(. | key('stamp-by-scott', concat(Group, '|', Scott))[1]) = 1]" mode="scott"/>
    </StampGroup>
</xsl:template>     

<xsl:template match="stamp" mode="scott">
    <stampvariants>
        <xsl:apply-templates select="key('stamp-by-scott', concat(Group, '|', Scott))[count(. | key('stamp-by-minor', concat(Group, '|', Scott, '|', Minor))[1]) = 1]" mode="minor"/>
    </stampvariants>
</xsl:template>         

<xsl:template match="stamp" mode="minor">
    <xsl:choose>
        <xsl:when test="not(Minor)">
            <xsl:apply-templates select="key('stamp-by-minor', concat(Group, '|', Scott, '|', Minor))"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:apply-templates select="."/>
        </xsl:otherwise>
    </xsl:choose>
</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>