使用Muenchian方法对元素进行分组

时间:2019-05-27 09:50:57

标签: xml xslt-1.0

根据他们节点中的第一个元素,我试图将所有相同的AsstTp分组在一起。因此,所有Scty元素都位于一个AsstTp元素之下,所有Csh元素都位于另一个AsstTp元素之下。如下:

<RpTrad>
<AsstTp>
  <Scty>
    <Id>
      <Id>GB00B3KJDQ49</Id>
      <ClssfctnTp>DBADGC</ClssfctnTp>
      <QtyOrNmnlVal>
        <NmnlVal Ccy="EUR">1000000</NmnlVal>
      </QtyOrNmnlVal>         
    </Id>
  </Scty>
</AsstTp>
<AsstTp>
  <Scty>
    <Id>
      <Id>GB00B3KJDP50</Id>
      <ClssfctnTp>DBADGC</ClssfctnTp>
      <QtyOrNmnlVal>
        <NmnlVal Ccy="GBP">1100000</NmnlVal>
      </QtyOrNmnlVal>         
    </Id>
  </Scty>
</AsstTp>
<AsstTp>
  <Scty>
    <Id>
      <Id>GB00B3KJDR51</Id>
      <ClssfctnTp>DBADGC</ClssfctnTp>
      <QtyOrNmnlVal>
        <NmnlVal Ccy="CHF">1200000</NmnlVal>
      </QtyOrNmnlVal>         
    </Id>
  </Scty>
</AsstTp>
<AsstTp>
  <Csh>
    <Id>
      <Id>US1234567890</Id>
      <ClssfctnTp>EABCDE</ClssfctnTp>
      <QtyOrNmnlVal>
        <Qty>10000</Qty>
      </QtyOrNmnlVal>         
    </Id>
  </Csh>
</AsstTp>
</RpTrad>

应该成为...

<RpTrad>
<AsstTp>
  <Scty>
    <Id>
      <Id>GB00B3KJDQ49</Id>
      <ClssfctnTp>DBADGC</ClssfctnTp>
      <QtyOrNmnlVal>
        <NmnlVal Ccy="EUR">1000000</NmnlVal>
      </QtyOrNmnlVal>         
    </Id>
  </Scty>
  <Scty>
    <Id>
      <Id>GB00B3KJDP50</Id>
      <ClssfctnTp>DBADGC</ClssfctnTp>
      <QtyOrNmnlVal>
        <NmnlVal Ccy="GBP">1100000</NmnlVal>
      </QtyOrNmnlVal>         
    </Id>
  </Scty>
  <Scty>
    <Id>
      <Id>GB00B3KJDR51</Id>
      <ClssfctnTp>DBADGC</ClssfctnTp>
      <QtyOrNmnlVal>
        <NmnlVal Ccy="CHF">1200000</NmnlVal>
      </QtyOrNmnlVal>         
    </Id>
  </Scty>
</AsstTp>   
<AsstTp>
  <Csh>
    <Id>
      <Id>US1234567890</Id>
      <ClssfctnTp>EABCDE</ClssfctnTp>
      <QtyOrNmnlVal>
        <Qty>10000</Qty>
      </QtyOrNmnlVal>         
    </Id>
  </Csh>
</AsstTp>
</RpTrad>

我目前正在尝试使用以下XSLT,但似乎只是重复了4次:

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

<xsl:key name="Coll-by-AsstTp" match="AsstTp" use="local-name()" />
<xsl:template match="RpTrad">
    <xsl:for-each select="AsstTp[count(. | key('Coll-by-AsstTp', local-name())[1]) = 1]">       
        <xsl:for-each select="key('Coll-by-AsstTp', local-name())">
            <xsl:copy-of select="/node()" />
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

因此,我认为创建密钥和使用local-name()函数未获取所需的正确元素值存在问题。因此,导致for循环运行了很多次,并没有深入到仅复制每个AsstTp的内部节点的水平。

预先感谢, 扫罗

1 个答案:

答案 0 :(得分:0)

您想按AsstTp个元素的子元素名称进行分组-因此,您的键应定义为:

<xsl:key name="asstTp-by-child" match="AsstTp" use="local-name(*)" />

然后:

XSLT 1.0

<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="asstTp-by-child" match="AsstTp" use="local-name(*)" />

<xsl:template match="/RpTrad">
    <xsl:copy>
        <xsl:for-each select="AsstTp[count(. | key('asstTp-by-child', local-name(*))[1]) = 1]"> 
            <xsl:copy>    
                <xsl:copy-of select="key('asstTp-by-child', local-name(*))/*"/>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

将返回您想要的结果。


注意

说明:

<xsl:copy-of select="/node()" />

无论当前上下文如何,都将从根节点开始复制整个XML文档。