1

我最近一直在使用 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>元素,并且每个元素都<Detail>被分组到第一个<Info>元素中,最后一个<Info>元素为空。

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

谢谢你的帮助 :)

4

1 回答 1

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. 请注意父母的身份是如何包含在密钥中的。

于 2012-10-01T13:39:25.133 回答