结合xslt分组

时间:2014-03-12 10:44:07

标签: xml xslt xslt-1.0 grouping nested-attributes

我的xml是

<?xml version="1.0" encoding="UTF-8"?> 
<struct name="foolist"> 
<!-- this is a comment -->  
<foo age="12" dob="2012">foo</foo>
<foo age="20" dob="1999">foo</foo>
<bar age="24">bar</bar>
</struct>

使用xslt 1.0的所需输出是

<?xml version="1.0" encoding="UTF-8"?>
<struct> 
   <c>     this is a comment    </c> 
   <s>   
      <s>      
         <foo> 
            <a> 
               <a>    
                  <a>age</a>    
                  <v>12</v>  
               </a> 
               <a>    
                  <a>dob</a>    
                  <v>2012</v>  
               </a>
            </a> 
            <v>foo</v>     
         </foo>     
         <foo> 
            <a>
               <a>    
                  <a>age</a>    
                  <v>20</v>  
               </a> 
               <a>    
                  <a>dob</a>    
                  <v>1999</v>  
               </a> 
            </a> 
            <v>foo</v>      
         </foo>  
      </s>   
      <s>    
         <bar> 
            <a>
               <a>    
                  <a>age</a>    
                  <v>20</v>  
               </a>
            </a> 
            <v>bar</v>      
         </bar>    
      </s> 
   </s> 
   <a>  
      <a>      
         <a>name</a>      
         <v>foolist</v>    
      </a> 
   </a> 
</struct>

我的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" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:strip-space elements="*"/>

 <xsl:key name="adjacentByName" match="*/*" use="generate-id(preceding-sibling::*[not(name()=name(current()))][1])" />

<xsl:template match="comment()|*">

        <xsl:copy>
        <xsl:apply-templates select ="comment()|*"/>
      <s>
        <xsl:for-each select="*/*[generate-id()=generate-id(key('adjacentByName', generate-id(preceding-sibling::*[not(name()=name(current()))][1]))[1])]">
    <s>
        <xsl:for-each select="key('adjacentByName', generate-id(preceding-sibling::*[not(name()=name(current()))][1]))">
            <xsl:copy-of select="."/>
        </xsl:for-each>
    </s>
</xsl:for-each>
 </s>  
          <a>
            <xsl:apply-templates select="@*" />
        </a>
        <xsl:apply-templates select="text()" />

    </xsl:copy> 

</xsl:template>



<!-- Matches all attributes -->
<xsl:template match="@*">
    <a>
        <a><xsl:value-of select="name()" /></a>
        <v><xsl:value-of select="." /></v>
    </a>
</xsl:template>

<!-- Matches text nodes -->
<xsl:template match="text()">
    <v><xsl:value-of select="." /></v>
</xsl:template>

<xsl:template match="comment()">
    <c><xsl:value-of select="." /></c>
</xsl:template>
</xsl:stylesheet>

我只是遇到问题&#34; s&#34;标签否则一切正常。我试图将所有相同的元素放在单独的&#34; s&#34;标签和根元素的所有子元素在一个&#34; s&#34;标签。  提前谢谢。

1 个答案:

答案 0 :(得分:0)

我觉得有点令人不安的是,在previous question of yours中,你问完全相同的事情,只是在相反的方向。那是为什么?

目前还不完全清楚规则和约束是什么,但我会尝试一下。

我已经重写了样式表,在我看来现在更容易理解。你仍然需要重新引入按键分组,但我知道这对你来说并不困难。

<强>样式表

<?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:strip-space elements="*"/>

   <xsl:key name="adjacent" match="*/*" use="generate-id(preceding-sibling::*[not(name()=name(current()))][1])" />

   <xsl:template match="/struct">
       <xsl:copy>
           <xsl:apply-templates select="comment()"/>
           <s>  
               <xsl:for-each select="*[generate-id()=generate-id(key('adjacent', generate-id(preceding-sibling::*[not(name()=name(current()))][1]))[1])]">
                   <s>
                      <xsl:apply-templates select="key('adjacent', generate-id(preceding-sibling::*[not(name()=name(current()))][1]))"/>
                   </s>
               </xsl:for-each>
           </s>
           <a>
               <xsl:apply-templates select="@*"/>
           </a>
       </xsl:copy>
   </xsl:template>

   <xsl:template match="comment()">
       <c>
           <xsl:value-of select="."/>
       </c>
   </xsl:template>

   <xsl:template match="foo|bar">
        <xsl:copy>
            <a>
                <xsl:apply-templates select="@*"/>
            </a>
            <xsl:apply-templates select="text()"/>
        </xsl:copy>
   </xsl:template>

   <xsl:template match="@*">
       <a>
           <a>
               <xsl:value-of select="name()"/>
           </a>
           <v>
               <xsl:value-of select="."/>
           </v>
       </a>
   </xsl:template>

   <xsl:template match="text()">
       <v>
           <xsl:value-of select="."/>
       </v>
   </xsl:template>

</xsl:stylesheet>

<强>输出

<?xml version="1.0" encoding="UTF-8"?>
<struct>
   <c> this is a comment </c>
   <s>
      <s>
         <foo>
            <a>
               <a>
                  <a>age</a>
                  <v>12</v>
               </a>
               <a>
                  <a>dob</a>
                  <v>2012</v>
               </a>
            </a>
            <v>foo</v>
         </foo>
         <foo>
            <a>
               <a>
                  <a>age</a>
                  <v>20</v>
               </a>
               <a>
                  <a>dob</a>
                  <v>1999</v>
               </a>
            </a>
            <v>foo</v>
         </foo>
      </s>
      <s>
         <bar>
            <a>
               <a>
                  <a>age</a>
                  <v>24</v>
               </a>
            </a>
            <v>bar</v>
         </bar>
      </s>
   </s>
   <a>
      <a>
         <a>name</a>
         <v>foolist</v>
      </a>
   </a>
</struct>