使用XSLT对XML进行分组

时间:2012-10-12 19:02:45

标签: xslt-1.0

我正在尝试创建一个标题详细信息XML文档,从另一个xml设置。

源xml文档:

<items>
    <item>
        <col1>H</col1>
        <col2>header1</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail1.1</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail1.2</col2>
    </item>
    <item>
        <col1>H</col1>
        <col2>header2</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail2.1</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail2.2</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail2.3</col2>
    </item>
</items>

期望的输出:

<xml>
    <transaction>
        <items>
            <item>
                <col1>H</col1>
                <col2>header1</col2>
            </item>
            <item>
                <col1>D</col1>
                <col2>detail1.1</col2>
            </item>
            <item>
                <col1>D</col1>
                <col2>detail1.2</col2>
            </item>
        </items>
    </transaction>
    <transaction>
        <items>
            <item>
                <col1>H</col1>
                <col2>header2</col2>
            </item>
            <item>
                <col1>D</col1>
                <col2>detail2.1</col2>
            </item>
            <item>
                <col1>D</col1>
                <col2>detail2.2</col2>
            </item>
            <item>
                <col1>D</col1>
                <col2>detail2.3</col2>
            </item>
        </items>
    </transaction>
</xml>

我尝试过的XSLT:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="/ | node() | @* | comment() | processing-instruction()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="item[col1='H']">
        <transaction>
            <xsl:apply-templates/>
        </transaction>
    </xsl:template>
</xsl:transform>

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="kItemByCol2Num" match="item[starts-with(col2, 'detail')]"
  use="substring-before(substring-after(col2, 'detail'), '.')"/>

 <xsl:key name="kItemByCol2Num" match="item[starts-with(col2, 'header')]"
  use="substring-after(col2, 'header')"/>

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

 <xsl:template match=
 "item
   [starts-with(col2, 'header')
  and
    generate-id()
   =
    generate-id(key('kItemByCol2Num', substring-after(col2, 'header'))[1])
   ]">
  <transaction>
    <xsl:copy-of select="key('kItemByCol2Num', substring-after(col2, 'header'))"/>
  </transaction>
 </xsl:template>
 <xsl:template match="item"/>
</xsl:stylesheet>

应用于提供的XML文档时:

<items>
    <item>
        <col1>H</col1>
        <col2>header1</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail1.1</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail1.2</col2>
    </item>
    <item>
        <col1>H</col1>
        <col2>header2</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail2.1</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail2.2</col2>
    </item>
    <item>
        <col1>D</col1>
        <col2>detail2.3</col2>
    </item>
</items>

会产生想要的正确结果:

<items>
   <transaction>
      <item>
         <col1>H</col1>
         <col2>header1</col2>
      </item>
      <item>
         <col1>D</col1>
         <col2>detail1.1</col2>
      </item>
      <item>
         <col1>D</col1>
         <col2>detail1.2</col2>
      </item>
   </transaction>
   <transaction>
      <item>
         <col1>H</col1>
         <col2>header2</col2>
      </item>
      <item>
         <col1>D</col1>
         <col2>detail2.1</col2>
      </item>
      <item>
         <col1>D</col1>
         <col2>detail2.2</col2>
      </item>
      <item>
         <col1>D</col1>
         <col2>detail2.3</col2>
      </item>
   </transaction>
</items>

<强>解释

  1. 正确使用Muenchian方法进行分组。

  2. 正确使用密钥。