Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XSLT为每个同级对子节点进行分组_Xslt_Grouping_Parent Child_Siblings - Fatal编程技术网

XSLT为每个同级对子节点进行分组

XSLT为每个同级对子节点进行分组,xslt,grouping,parent-child,siblings,Xslt,Grouping,Parent Child,Siblings,我最近一直在使用XSLT,但现在我遇到了一个新问题,那就是如何对新的xml文件进行分组。我不知道如何在分组上设置范围。我想在每个节点内部对节点进行分组。简单示例文件: <?xml version="1.0" encoding="utf-8"?> <File> <Info> <Id>1111</Id> <Detail type="A" group="1" > <Data> <

我最近一直在使用XSLT,但现在我遇到了一个新问题,那就是如何对新的xml文件进行分组。我不知道如何在分组上设置范围。我想在每个节点内部对节点进行分组。简单示例文件:

<?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>
在我的尝试中,我不知道如何从元素ID复制值,它也可能是其他元素,我只是写出元素,每个元素都在第一个元素中分组,最后一个元素为空

到目前为止,这里是我的xslt

<?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>
这是我到目前为止的结果

<File>
  <Info>
    <Detail type="A" group="1">
      <Data>
        <Nr>1</Nr>
      </Data>
      <Data>
        <Nr>2</Nr>
      </Data>
      <Data>
        <Nr>6</Nr>
      </Data>
      <Data>
        <Nr>1</Nr>
      </Data>
      <Data>
        <Nr>3</Nr>
      </Data>
    </Detail>
    <Detail type="B" group="1">
      <Data>
        <Nr>3</Nr>
      </Data>
      <Data>
        <Nr>4</Nr>
      </Data>
      <Data>
        <Nr>2</Nr>
      </Data>
    </Detail>
    <Detail type="B" group="2">
      <Data>
        <Nr>5</Nr>
      </Data>
    </Detail>
  </Info>
  <Info />
</File>
感谢您的帮助:

此转换:

应用于提供的XML文档时:

生成所需的正确结果:

说明:

正确使用身份规则和使用复合密钥的Muenchian分组方法

注意父项的标识是如何包含在密钥中的


感谢您提供了一个很好的答案,以真正的格式重用效果很好。我现在将用一些时间来理解流程。
<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>
<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>