加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

xml – 使用Muenchian方法对多个键进行XSLT分组

发布时间:2020-12-16 07:57:19 所属栏目:百科 来源:网络整理
导读:这是输入文件. 所有这些块都包含在 allocfile中.不出现的标签,不知道为什么?并且所有这些块都包含在顶级元素 xml中. XML AllocFile alc1/alc No11/10/No DT20090401/DT G_H147/G_H FUN125487/FUN oH11/oH y9/y AMOUNT8000000/AMOUNT Code033195/Code hd1123
这是输入文件.

所有这些块都包含在< allocfile>中.不出现的标签,不知道为什么?并且所有这些块都包含在顶级元素< xml>中.

<XML>
  <AllocFile>
    <alc>1</alc>
    <No>11/10</No>
    <DT>20090401</DT> 
    <G_H>147</G_H>
    <FUN>125487</FUN>
    <oH>11</oH>
    <y>9</y>
    <AMOUNT>8000000</AMOUNT>
    <Code>033195</Code>
    <hd1>1234</hd1>
  </AllocFile>
  <AllocFile>
    <alc>2</alc>
    <No>14/10</No>
    <DT>20090401</DT>
    <G_H>147</G_H>
    <FUN>125487</FUN>
    <oH>11</oH>
    <y>9</y>
    <AMOUNT>8400000</AMOUNT>
    <Code>033195</Code>
    <hd1>1234</hd1>
  </AllocFile>
  <AllocFile>
    <alc>3</alc>
    <No>74/10</No>
    <DT>20090401</DT>
    <G_H>147</G_H>
    <FUN>125487</FUN>
    <oH>11</oH>
    <y>9</y>
    <AMOUNT>8740000</AMOUNT>
    <Code>033195</Code>
    <hd1>1234</hd1>
  </AllocFile>
  <AllocFile>
    <alc>2</alc>
    <No>74/10</No>
    <DT>20090401</DT>
    <G_H>117</G_H>
    <FUN>125487</FUN>
    <oH>19</oH>
    <y>9</y>
    <AMOUNT>74512</AMOUNT>
    <Code>033118</Code>
    <hd1>1234</hd1>
  </AllocFile>
  <AllocFile>
    <alc>3</alc>
    <No>14/10</No>
    <DT>20090401</DT>
    <G_H>117</G_H>
    <FUN>125487</FUN>
    <oH>19</oH>
    <y>9</y>
    <AMOUNT>986541</AMOUNT>
    <Code>033147</Code>
    <hd1>1234</hd1>
  </AllocFile> 
</XML>

输出是

<Header1>
  <Hd1>1234</Hd1>
  <CodeHeader>
    <Code>033195</Code>
    <Header2>
      <G_H>147</G_H>
      <FUN>125487</FUN>
      <oH>11</oH>
      <y>9</y>
      <allocheader>
        <alc>1</alc>
        <No>11/10</No>
        <DT>20090401</DT>
        <AMOUNT>8000000</AMOUNT>
      </allocheader>
      <allocheader>
        <alc>2</alc>
        <No>14/10</No>
        <DT>20090401</DT>
        <AMOUNT>8400000</AMOUNT>
      </allocheader>
      <allocheader>
        <alc>3</alc>
        <No>74/10</No>
        <DT>20090401</DT>
        <AMOUNT>8740000</AMOUNT>
      </allocheader>
    </Header2>
  </CodeHeader>
  <CodeHeader>
        <Code>033118</Code>
        <Header2>
      <G_H>117</G_H>
      <FUN>125487</FUN>
         <oH>19</oH>
            <y>9</y>
             <allocheader>
             <alc>2</alc>
             <No>74/10</No>
             <DT>20090401</DT>
             <AMOUNT>74512</AMOUNT>
           </allocheader>
       </Header2>
    </codeHeader>
   <CodeHeader>
        <Code>033147</Code>
           <Header2>
          <G_H>117</G_H>
          <FUN>125487</FUN>
          <oH>19</oH>
          <y>9</y>
         <allocheader>
           <alc>3</alc>
            <No>14/10</No>
            <DT>20090401</DT>
            <AMOUNT>986541</AMOUNT>
          </allocheader>
         </Header2>
      </CodeHeader>
</Header1>

输入文件需要根据多个键进行排序和分组.我继续使用concat函数和Muenchian方法,但没有从网上获得太多帮助.我正在使用XSLT 1.0.

分组规则

>文件中的所有节点都将具有< hd1>值为1234 ..这将成为按键的第一个组,并在输出中显示为< Header1>

>分组的第二个键是节点代码.具有相同值的节点被组合在一起.出现为.代码头

>第二个键是节点组G_H,FUN,oH,y.如果所有这些节点具有相同的值,则它们将组合在一起.它在输出中显示为< Header2>
>节点上没有分组< alc>,< No>,< DT>,< AMOUNT>.它们在每个组中都有不同的值.

如果hd1元素总是’1234′,那么你实际上并不是按它们分组,但如果你是,你会定义一个简单的键,如此
<xsl:key name="header1" match="AllocFile" use="hd1" />

对于第二个键,您需要考虑Code元素

<xsl:key name="header2" match="AllocFile" use="concat(hd1,'|',Code)" />

然后对于最后一个键,您将定义一个更复杂的键来处理所有元素

<xsl:key name="header3" 
   match="AllocFile" 
   use="concat(hd1 '|',Code,G_H,y)" />

请注意使用’pipe’字符作为分隔符.选择在任何所选元素中永远不会出现的分隔符非常重要.

然后,要查找不同的header1元素,您将查找header1键中首先出现的元素

<xsl:apply-templates 
   select="AllocFile[generate-id() = generate-id(key('header1',hd1)[1])]" 
   mode="header1" />

要在每个header1元素中查找不同的Code元素,您将执行以下操作

<xsl:apply-templates 
   select="key('header1',hd1)
     [generate-id() = generate-id(key('header2',concat(hd1,Code))[1])]" 
   mode="header2" />

最后,在每个代码组中,要查找不同的“header3”元素,您将查找第三个键中的第一个元素

<xsl:apply-templates 
 select="key('header2',Code))
    [generate-id() = 
     generate-id(key('header3',y))[1])]" 
 mode="header3" />

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:key name="header1" match="AllocFile" use="hd1"/>
   <xsl:key name="header2" match="AllocFile" use="concat(hd1,Code)"/>
   <xsl:key name="header3" match="AllocFile" use="concat(hd1,y)"/>

   <xsl:template match="/XML">
      <xsl:apply-templates select="AllocFile[generate-id() = generate-id(key('header1',hd1)[1])]" mode="header1"/>
   </xsl:template>

   <xsl:template match="AllocFile" mode="header1">
      <Header1>
         <Hd1>
            <xsl:value-of select="hd1"/>
         </Hd1>
         <xsl:apply-templates select="key('header1',hd1)[generate-id() = generate-id(key('header2',Code))[1])]" mode="header2"/>
      </Header1>
   </xsl:template>

   <xsl:template match="AllocFile" mode="header2">
      <CodeHeader>
         <xsl:copy-of select="Code"/>
         <xsl:apply-templates select="key('header2',Code))[generate-id() = generate-id(key('header3',y))[1])]" mode="header3"/>
      </CodeHeader>
   </xsl:template>

   <xsl:template match="AllocFile" mode="header3">
      <Header2>
         <xsl:copy-of select="G_H|FUN|oH|y"/>
         <xsl:apply-templates select="key('header3',y))"/>
      </Header2>
   </xsl:template>

   <xsl:template match="AllocFile">
      <allocheader>
         <xsl:copy-of select="alc|No|DT|AMOUNT"/>
      </allocheader>
   </xsl:template>
</xsl:stylesheet>

请注意在模板匹配上使用mode属性以区分与AllocFile元素匹配的多个模板.

应用于示例XML时,将输出以下内容

<Header1>
   <Hd1>1234</Hd1>
   <CodeHeader>
      <Code>033195</Code>
      <Header2>
         <G_H>147</G_H>
         <FUN>125487</FUN>
         <oH>11</oH>
         <y>9</y>
         <allocheader>
            <alc>1</alc>
            <No>11/10</No>
            <DT>20090401</DT>
            <AMOUNT>8000000</AMOUNT>
         </allocheader>
         <allocheader>
            <alc>2</alc>
            <No>14/10</No>
            <DT>20090401</DT>
            <AMOUNT>8400000</AMOUNT>
         </allocheader>
         <allocheader>
            <alc>3</alc>
            <No>74/10</No>
            <DT>20090401</DT>
            <AMOUNT>8740000</AMOUNT>
         </allocheader>
      </Header2>
   </CodeHeader>
   <CodeHeader>
      <Code>033118</Code>
      <Header2>
         <G_H>117</G_H>
         <FUN>125487</FUN>
         <oH>19</oH>
         <y>9</y>
         <allocheader>
            <alc>2</alc>
            <No>74/10</No>
            <DT>20090401</DT>
            <AMOUNT>74512</AMOUNT>
         </allocheader>
      </Header2>
   </CodeHeader>
   <CodeHeader>
      <Code>033147</Code>
      <Header2>
         <G_H>117</G_H>
         <FUN>125487</FUN>
         <oH>19</oH>
         <y>9</y>
         <allocheader>
            <alc>3</alc>
            <No>14/10</No>
            <DT>20090401</DT>
            <AMOUNT>986541</AMOUNT>
         </allocheader>
      </Header2>
   </CodeHeader>
</Header1>

如果你确实有不同的hd1元素,除了’1234’之外你最终会得到多个Header1元素,因此你的输出将不是格式良好的XML.通过修改与文档元素匹配的初始模板,将它们包装在根元素中会很简单.

<xsl:template match="/XML">
   <Root>
      <xsl:apply-templates select="AllocFile[generate-id() = generate-id(key('header1',hd1)[1])]" mode="header1" />
   </Root>
</xsl:template>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读