xslt - 将重复的节点排序到不同的div中

时间:2012-08-27 10:46:34

标签: xml xslt xslt-1.0

这是我的xml输入

<issues>
  <issue status="open" type="Bug">
    <fix_versions>
      <fix_version>6.14.0</fix_version>
      <fix_version>6.13.0</fix_version>
      <fix_version>6.12.0</fix_version>
    </fix_versions>
    <title>issue1</title>
    <description>Description</description>
  </issue>
  <issue status="open" type="Feature">
    <fix_versions>
      <fix_version>6.13.0</fix_version>
    </fix_versions>
    <title>issue2</title>
    <description>Description</description>
  </issue>
  <issue status="open" type="Improvement">
    <fix_versions>
      <fix_version>6.14.0</fix_version>
    </fix_versions>
    <title>issue3</title>
    <description>Description</description>
  </issue>
</issues>

这是我的xsl代码

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


<xsl:key name="versions" match="issue" use="fix_versions"/>
<xsl:key name="type" match="issue" use="concat(fix_versions, '+', @type)"/>

<xsl:template match="issues">



  <xsl:for-each select="//issue[generate-id(.)=generate-id(key('versions', fix_versions)[1])]">

    <xsl:sort select="fix_versions" order="descending"/> 



        <xsl:variable name="version"><xsl:value-of select="fix_versions"/></xsl:variable>


                <xsl:if test="//release[@version = \$version]">
                    <div class="release">
                    <a href="" class="version"><xsl:value-of select="\$version"/></a>
                    <div class="version" style="display:none;">
                        <xsl:for-each select="key('versions', fix_versions)[generate-id() = generate-id(key('type', concat(fix_versions, '+', @type))[1])]">
                            <div class="types">
                                <a href="" class="type"><xsl:value-of select="@type"/>s</a>
                                <div class="type" style="display:none">
                    <xsl:for-each select="key('type', concat(fix_versions, '+', @type))">
                        <div style="border-bottom:1px solid grey;">
                        <a href="" class="title"><xsl:value-of select="title"/></a>
                        <div class="toggle" style="display:none;">
                            <xsl:value-of select="description"/>
                        </div>
                        </div>
                                </xsl:for-each>
                                </div>
                            </div>                      
                </xsl:for-each>

            </div>
            </div>
                </xsl:if>


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

这就是我得到的

<div class="version">
  <a>6.14.0</a>
  <div class="issues">
    <div class="Bugs">
      <a href="issue1">issue1</a>
      <a href="issue7">issue7</a>
      <a href="issue2">issue12</a>
      <a href="issue17">issue17</a>
    </div>
    <div class="Improvements">
      <a href="issue3">issue3</a>
      <a href="issue9">issue9</a>
    </div>
  </div>
</div>
<div class="version">
  <a>6.13.0</a>
  <div class="issues">
    <div class="Bug">
      <a href="issue1">issue1</a>
      <a href="issue11">issue11</a>
    </div>
    <div class="Feature">
      <a href="issue2">issue2</a>
    </div>
  </div>
 </div>
 <div class="version">
   <a>6.12.0</a>
   <div class="issues">
     <div class="Bug">
       <a href="issue1">issue1</a>
     </div>
   </div>
</div>

一切都很好 - 唯一的问题是我只生成fix_versions的密钥,但我的结构为fix_versions/fix_version。因此,如果存在类似<fix_versions> <fix_version>6.14.0</fix_version> <fix_version>6.13.0</fix_version> <fix_version>6.12.0</fix_version> </fix_versions>的节点,他将创建密钥6.14.06.13.06.12.0并为此版本创建容器 - 但我想要的是将此问题放入三个容器{{1} },6.14.06.13.0。是否可以复制一个问题?

我尝试了类似6.12.0的内容,然后使用<xsl:key name="versions" match="issue" use="fix_versions"/>,但他只是创建了一个大群,而不是将这个问题整理到所有群组中。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

基于猜测想要的结果

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

 <xsl:key name="kVersByVal" match="fix_version" use="."/>
 <xsl:key name="kBugTypeByVers" match="@type" use="../*/fix_version"/>

 <xsl:template match=
  "fix_version[generate-id()=generate-id(key('kVersByVal',.)[1])]">
  <div class="version">
   <a><xsl:value-of select="."/></a>
   <div class="issues">
     <xsl:for-each select="key('kBugTypeByVers',.)">
       <div class="{.}">
         <a href="{../title}"><xsl:value-of select="../title"/></a>
       </div>
     </xsl:for-each>
   </div>
  </div>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

在提供的XML文档上应用此转换时

<issues>
  <issue status="open" type="Bug">
    <fix_versions>
      <fix_version>6.14.0</fix_version>
      <fix_version>6.13.0</fix_version>
      <fix_version>6.12.0</fix_version>
    </fix_versions>
    <title>issue1</title>
    <description>Description</description>
  </issue>
  <issue status="open" type="Feature">
    <fix_versions>
      <fix_version>6.13.0</fix_version>
    </fix_versions>
    <title>issue2</title>
    <description>Description</description>
  </issue>
  <issue status="open" type="Improvement">
    <fix_versions>
      <fix_version>6.14.0</fix_version>
    </fix_versions>
    <title>issue3</title>
    <description>Description</description>
  </issue>
</issues>

产生假定的,正确的结果

<div class="version">
   <a>6.14.0</a>
   <div class="issues">
      <div class="Bug">
         <a href="issue1">issue1</a>
      </div>
      <div class="Improvement">
         <a href="issue3">issue3</a>
      </div>
   </div>
</div>
<div class="version">
   <a>6.13.0</a>
   <div class="issues">
      <div class="Bug">
         <a href="issue1">issue1</a>
      </div>
      <div class="Feature">
         <a href="issue2">issue2</a>
      </div>
   </div>
</div>
<div class="version">
   <a>6.12.0</a>
   <div class="issues">
      <div class="Bug">
         <a href="issue1">issue1</a>
      </div>
   </div>
</div>