如何在xsl1.0和2.0中对元素进行分组?

时间:2012-05-14 13:56:50

标签: xslt

这样的例子

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <a id='a1' name='a1 is a Chinese pig'/>
    <b text='b1'/>
    <d test='test0' location='L0' text='c0'/>
    <a id='a2' name='a2 is a Japanese pig'/>
    <b text='b2'/>
    <c test='test1' location='L1' text='c1 is a red pig'/>
    <c test='test2' location='L2' text='c2 is a green pig'/>
    <a id='a3' name='a3 is a American dog'/>
    <b text='b3'/>
    <c test='test3' location='L3' text='c3 is a lovely dog'/>
    <c test='test4' location='L4' text='c4 is a ugly dog'/>
    <c test='test5' location='L5' text='c5 is a smart dog'/>
    <a id='a4' name='a4 is a Japanese bird'/>
    <b text='b4'/>
    <c test='test6' location='L6' text='c6 is a lovely bird'/>
    <c test='test7' location='L7' text='c7 is a ugly bird'/>
    <c test='test8' location='L8' text='c8 is a smart bird'/>   
    <a id='a5' name='a5 is a American pig'/>
    <b text='b2'/>
    <c test='test10' location='L10' text='c10 is a red pig'/>
    <c test='test11' location='L11' text='c11 is a green pig'/>
    <a id='a6' name='a6 is a Chinese dog'/>
    <b text='b3'/>
    <c test='test12' location='L12' text='c12 is a lovely dog'/>
    <c test='test14' location='L14' text='c14 is a ugly dog'/>
    <c test='test15' location='L15' text='c15 is a smart dog'/>
    <a id='a7' name='a7 is a Chinese bird'/>
    <b text='b4'/>
    <c test='test16' location='L16' text='c16 is a lovely bird'/>
    <c test='test17' location='L17' text='c17 is a ugly bird'/>
    <c test='test18' location='L18' text='c18 is a smart bird'/>        
</root>

我像这样应用xsl1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="text" indent="yes"/>

   <xsl:key name="lookup" match="c" use="generate-id(preceding-sibling::a[1])" />
   <xsl:template match="/root">
      <xsl:apply-templates select="a[key('lookup', generate-id())]" />
   </xsl:template>

   <xsl:template match="a">dog:<xsl:value-of select="concat(@name[contains(.,'dog')], ':&#13;', '&#13;')" />
      <xsl:apply-templates select="key('lookup', generate-id())" />
   </xsl:template>

   <xsl:template match="c">
      <xsl:apply-templates select="@*" />
      <xsl:value-of select="'&#13;'" />
   </xsl:template>

   <xsl:template match="c/@*">
      <xsl:value-of select="concat(local-name(), ':', ., ':&#13;')" />
   </xsl:template>
</xsl:stylesheet>

我想要这样的输出,规则是

  1. 如果元素和下一个元素之间有一个或多个c元素,那么我们输出这些c元素
  2. 然后根据@name,检查该值是否包含猪,狗或鸟等字符串,这些是关键词,而不仅仅是硬代码。我们可以将这些信息分组,因为有更多的猪,鸟和狗。不管它们是中国人还是日本人,或者我们根据我们之前所知的那些类别的狗,鸟,猪分组。
  3. 我想要的输出就像这样

    case1:the following are  all pigs:
    
    a2 is a Japanese pig
    
    test:test1
    location:L1
    text:c1 is a red pig
    test:test2
    location:L2
    text:c2 is a green pig
    
    a5 is a American pig
    
    test:test10
    location:L10
    text:c10 is a red pig
    test:test11
    location:L11
    text:c11 is a green pig
    
    case2:the following are  all dogs:
    
    a3 is a American dog
    
    test:test3
    location:L3
    text:c3 is a lovely dog
    
    test:test4
    location:L4
    text:c4 is a ugly dog
    
    test:test5
    location:L5
    text:c5 is a smart dog
    
    a6 is a Chinese dog
    
    test:test12
    location:L12
    text:c12 is a lovely dog
    
    test:test14
    location:L14
    text:c14 is a ugly dog
    
    test:test15
    location:L15
    text:c15 is a smart dog    
    
    case3:the following are  all birds:
    
    a4 is a Japanese bird
    test:test6
    location:L6
    text:c6 is a lovely bird
    
    test:test7
    location:L7
    text:c7 is a ugly bird
    
    test:test8
    location:L8
    text:c8 is a smart bird
    
    a7 is a Chinese bird
    
    test:test16
    location:L16
    text:c16 is a lovely bird
    
    test:test17
    location:L17
    text:c17 is a ugly bird
    
    test:test18
    location:L18
    text:c18 is a smart bird   
    

    问题是如何纠正我的xsl1.0?另一个是这在xsl2.0中更容易实现吗?

1 个答案:

答案 0 :(得分:1)

使用此xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="text" indent="yes"/>
   <xsl:template match="/root">
      <p>the followings are birds:</p>
      <xsl:apply-templates select="a[contains(@name, 'bird')][key('bird_lookup', generate-id())]"/>
      <p>the followings are pigs:</p>
      <xsl:apply-templates select="a[contains(@name, 'pig')][key('pig_lookup', generate-id())]"/> 
      <p>the followings are dogs:</p>
      <xsl:apply-templates select="a[contains(@name, 'dog')][key('dog_lookup', generate-id())]"/>                
   </xsl:template>
   <xsl:key name="bird_lookup" match="c" use="generate-id(preceding-sibling::a[1][contains(@name, 'bird')])"/>
   <xsl:template name="bird" match="a[contains(@name, 'bird')]">
      <xsl:value-of select="'&#13;'"/> 
      <xsl:value-of select="@name"/>
      <xsl:value-of select="'&#13;'"/>      
      <xsl:apply-templates select="key('bird_lookup', generate-id())" />
      <xsl:apply-templates select="c/@*"/>
   </xsl:template>

   <xsl:key name="pig_lookup" match="c" use="generate-id(preceding-sibling::a[1][contains(@name, 'pig')])"/>
   <xsl:template name="pig" match="a[contains(@name, 'pig')]">
         <xsl:value-of select="'&#13;'"/> 
      <xsl:value-of select="@name"/>
      <xsl:value-of select="'&#13;'"/>      
      <xsl:apply-templates select="key('pig_lookup', generate-id())" />
      <xsl:apply-templates select="c/@*"/>
   </xsl:template>

      <xsl:key name="dog_lookup" match="c" use="generate-id(preceding-sibling::a[1][contains(@name, 'dog')])"/>
   <xsl:template name="dog" match="a[contains(@name, 'dog')]">
      <xsl:value-of select="'&#13;'"/>     
      <xsl:value-of select="@name"/>
      <xsl:value-of select="'&#13;'"/>      
      <xsl:apply-templates select="key('dog_lookup', generate-id())" />
      <xsl:apply-templates select="c/@*"/>
   </xsl:template>


   <xsl:template match="c">
      <xsl:apply-templates select="@*"/>
      <xsl:value-of select="'&#13;'"/>
   </xsl:template>

   <xsl:template match="c/@*">
      <xsl:value-of select="concat(local-name(), ':', ., '&#13;')"/>
   </xsl:template>

</xsl:stylesheet>

我可以

the followings are birds:
a4 is a Japanese bird
test:test6
location:L6
text:c6 is a lovely bird

test:test7
location:L7
text:c7 is a ugly bird

test:test8
location:L8
text:c8 is a smart bird


a7 is a Chinese bird
test:test16
location:L16
text:c16 is a lovely bird

test:test17
location:L17
text:c17 is a ugly bird

test:test18
location:L18
text:c18 is a smart bird

the followings are pigs:
a2 is a Japanese pig
test:test1
location:L1
text:c1 is a red pig

test:test2
location:L2
text:c2 is a green pig


a5 is a American pig
test:test10
location:L10
text:c10 is a red pig

test:test11
location:L11
text:c11 is a green pig

the followings are dogs:
a3 is a American dog
test:test3
location:L3
text:c3 is a lovely dog

test:test4
location:L4
text:c4 is a ugly dog

test:test5
location:L5
text:c5 is a smart dog


a6 is a Chinese dog
test:test12
location:L12
text:c12 is a lovely dog

test:test14
location:L14
text:c14 is a ugly dog

test:test15
location:L15
text:c15 is a smart dog

如何让这个优雅?