XSLT为每个兄弟分组子节点

时间:2012-10-01 13:18:08

标签: xslt grouping parent-child siblings

我最近一直在使用XSLT,但现在我遇到了一个新问题,试图将新的xml文件分组。我无法弄清楚如何将范围放在分组上。我想将<Detail>分组到每个<Info>节点内。简单示例文件:

<?xml version="1.0" encoding="utf-8"?>
<File>
  <Info>
    <Id>1111</Id>
  <Detail type="A" group="1" >
    <Data>
      <Nr>1</Nr>
    </Data>
    <Data>
      <Nr>2</Nr>
    </Data>
  </Detail>
  <Detail type="B" group="1">
    <Data>
      <Nr>3</Nr>
    </Data>
    <Data>
      <Nr>4</Nr>
    </Data>
  </Detail>
  <Detail type="B" group="2">
    <Data>
      <Nr>5</Nr>
    </Data>
  </Detail>
  <Detail type="A" group="1">
    <Data>
      <Nr>6</Nr>
    </Data>
  </Detail>
 </Info>
 <Info>
   <Id>2222</Id>
    <Detail type="A" group="1" >
      <Data>
        <Nr>1</Nr>
      </Data>
    </Detail>
    <Detail type="B" group="1">
      <Data>
        <Nr>2</Nr>
      </Data>
    </Detail>
    <Detail type="A" group="1">
      <Data>
        <Nr>3</Nr>
      </Data>
    </Detail>
  </Info>
</File>

输出应为

<?xml version="1.0" encoding="utf-8"?>
<File>
  <Info>
    <Id>1111</Id>
  <Detail type="A" group="1" >
    <Data>
      <Nr>1</Nr>
    </Data>
    <Data>
      <Nr>2</Nr>
    </Data>
      <Data>
      <Nr>6</Nr>
    </Data>
  </Detail>
  <Detail type="B" group="1">
    <Data>
      <Nr>3</Nr>
    </Data>
    <Data>
      <Nr>4</Nr>
    </Data>
  </Detail>
  <Detail type="B" group="2">
    <Data>
      <Nr>5</Nr>
    </Data>
  </Detail>
 </Info>
 <Info>
   <Id>2222</Id>
    <Detail type="A" group="1" >
      <Data>
        <Nr>1</Nr>
      </Data>
          <Data>
        <Nr>3</Nr>
      </Data>
    </Detail>
    <Detail type="B" group="1">
      <Data>
        <Nr>2</Nr>
      </Data>
    </Detail>
  </Info>
</File>

在我的尝试中,我不知道如何复制<Info>元素中的值(ID,也可能是其他元素),我只写出<Info>元素,每个{{ 1}}在第一个<Detail>元素中分组,将最后一个<Info>元素留空。

到目前为止,这是我的xslt

<Info>

这是我到目前为止的结果

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

  <xsl:key name="details" match="Detail"
          use="concat(@type,'_',@group)"/>
  <xsl:template match='/'>
    <File>
      <xsl:for-each select="File/Info">
        <Info>
        <xsl:for-each select="Detail[count(. | key('details', concat(@type,'_',@group))[1]) = 1]">
        <xsl:sort select="concat(@type,'_',@group)" />
        <Detail type="{@type}" group="{@group}">
          <xsl:for-each select="key('details', concat(@type,'_',@group))">
            <xsl:copy-of select="Data"/>
          </xsl:for-each>
        </Detail>
        </xsl:for-each>
        </Info>
      </xsl:for-each>
    </File>
  </xsl:template>
</xsl:stylesheet>

感谢您的帮助:)

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="kDetailChildren" match="Detail"
  use="concat(generate-id(..),'+',@type,'+',@group)"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match=
 "Detail
   [not(generate-id()
       =
        generate-id(key('kDetailChildren',
                        concat(generate-id(..),'+',@type,'+',@group)
                        )[1])
        )]"/>
 <xsl:template match="Detail">
  <Detail>
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates select=
    "key('kDetailChildren',
         concat(generate-id(..),'+',@type,'+',@group)
         )/node()"/>
  </Detail>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时:

<File>
    <Info>
        <Id>1111</Id>
        <Detail type="A" group="1" >
            <Data>
                <Nr>1</Nr>
            </Data>
            <Data>
                <Nr>2</Nr>
            </Data>
        </Detail>
        <Detail type="B" group="1">
            <Data>
                <Nr>3</Nr>
            </Data>
            <Data>
                <Nr>4</Nr>
            </Data>
        </Detail>
        <Detail type="B" group="2">
            <Data>
                <Nr>5</Nr>
            </Data>
        </Detail>
        <Detail type="A" group="1">
            <Data>
                <Nr>6</Nr>
            </Data>
        </Detail>
    </Info>
    <Info>
        <Id>2222</Id>
        <Detail type="A" group="1" >
            <Data>
                <Nr>1</Nr>
            </Data>
        </Detail>
        <Detail type="B" group="1">
            <Data>
                <Nr>2</Nr>
            </Data>
        </Detail>
        <Detail type="A" group="1">
            <Data>
                <Nr>3</Nr>
            </Data>
        </Detail>
    </Info>
</File>

会产生想要的正确结果:

<File>
   <Info>
      <Id>1111</Id>
      <Detail type="A" group="1">
         <Data>
            <Nr>1</Nr>
         </Data>
         <Data>
            <Nr>2</Nr>
         </Data>
         <Data>
            <Nr>6</Nr>
         </Data>
      </Detail>
      <Detail type="B" group="1">
         <Data>
            <Nr>3</Nr>
         </Data>
         <Data>
            <Nr>4</Nr>
         </Data>
      </Detail>
      <Detail type="B" group="2">
         <Data>
            <Nr>5</Nr>
         </Data>
      </Detail>
   </Info>
   <Info>
      <Id>2222</Id>
      <Detail type="A" group="1">
         <Data>
            <Nr>1</Nr>
         </Data>
         <Data>
            <Nr>3</Nr>
         </Data>
      </Detail>
      <Detail type="B" group="1">
         <Data>
            <Nr>2</Nr>
         </Data>
      </Detail>
   </Info>
</File>

<强>解释

  1. 使用复合键正确使用身份规则 Muenchian 分组方法。

  2. 请注意父母的身份如何包含在密钥中。