首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSLT数据合并

XSLT数据合并
EN

Stack Overflow用户
提问于 2013-08-27 13:14:16
回答 2查看 104关注 0票数 2

我对XSLT有着非常基本的知识,我目前正在努力实现一些我仍在努力寻找的东西,如果可能的话。

可以是XSLT1.0或2.0

基本上这是我的XML的结构。

代码语言:javascript
复制
   <?xml version="1.0" encoding="windows-1252"?>
<Root>
    <DataPage>
        <Record>
            <TEMP>xxx</TEMP>
            <DEBITNO>6250281</DEBITNO>
            <DOSSIERNUMMERINT>2012365</DOSSIERNUMMERINT>
            <ID>0123456789Z60</ID>
            <DATE>31/01/2013</DATE>
            <YEAR>2006</YEAR>
            <DESC>Test Item 1</DESC>
            <AMOUNT>           38170.0000000</AMOUNT>
            <HEAD>123</HEAD>
        </Record>
    </DataPage>
    <DataPage>
        <Record>
            <TEMP>xxx</TEMP>
            <DEBITNO>6250281</DEBITNO>
            <DOSSIERNUMMERINT>2012365</DOSSIERNUMMERINT>
            <ID>0123456789Z70</ID>
            <DATE>22/02/2013</DATE>
            <YEAR>2006</YEAR>
            <DESC>Test Item 2</DESC>
            <AMOUNT>           14410.0000000</AMOUNT>
            <HEAD>123</HEAD>
        </Record>
    </DataPage>
    <DataPage>
        <Record>
            <TEMP>xxx</TEMP>
            <DEBITNO>3849322</DEBITNO>
            <DOSSIERNUMMERINT>20132394</DOSSIERNUMMERINT>
            <ID>34958701223Z20</ID>
            <DATE>06/01/2013</DATE>
            <YEAR>2006</YEAR>
            <DESC>Test Item 1</DESC>
            <AMOUNT>           33811.0000000</AMOUNT>
            <HEAD>567</HEAD>
        </Record>
    </DataPage>
</Root>

我想要这个输出如下

代码语言:javascript
复制
<?xml version="1.0" encoding="windows-1252"?>
<Root>
    <DataPage>
        <Record>
            <TEMP>xxx</TEMP>
            <DEBITNO>6250281</DEBITNO>
            <DOSSIERNUMMERINT>2012365</DOSSIERNUMMERINT>
            <Line>
                <ID>0123456789Z60</ID>
                <DATE>31/01/2013</DATE>
                <YEAR>2006</YEAR>
                <DESC>Test Item 1</DESC>
                <AMOUNT>           38170.0000000</AMOUNT>
            </Line>
            <Line>
                <ID>0123456789Z70</ID>
                <DATE>22/02/2013</DATE>
                <YEAR>2006</YEAR>
                <DESC>Test Item 2</DESC>
                <AMOUNT>           14410.0000000</AMOUNT>
            </Line>
            <HEAD>123</HEAD>
        </Record>
    </DataPage>
    <DataPage>
        <Record>
            <TEMP>xxx</TEMP>
            <DEBITNO>3849322</DEBITNO>
            <DOSSIERNUMMERINT>20132394</DOSSIERNUMMERINT>
            <Line>
                <ID>34958701223Z20</ID>
                <DATE>06/01/2013</DATE>
                <YEAR>2006</YEAR>
                <DESC>Test Item 1</DESC>
                <AMOUNT>           33811.0000000</AMOUNT>
            </Line>
            <HEAD>567</HEAD>
        </Record>
    </DataPage>
</Root>

因此,逻辑是将所有记录与相同的DEBITNO合并。

合并的规则是除ID、日期、年份、DESC和金额之外的所有内容,可以从第一次出现开始。

ID、日期、年份、DESC和金额需要放置在标签中,因此,如果有2条具有相同DEBITNO的记录,则将有2行项,如果有5条记录具有相同的DEBITNO,则生成的记录将有5行项。

我希望这是有意义的。

这样的事有可能吗?

致以敬意,

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-27 18:23:46

出于对凯先生关于不提供解决方案的决定的尊重,XSLT1.0中的这个解决方案解决了您的特殊情况,也是一个更一般情况的解决方案,在这种情况下,您可以拥有一个具有多个multiroot元素的root并且需要本地分组。

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
  <xsl:key name ="k1" match="DataPage[
    not(preceding-sibling::DataPage/Record/DEBITNO = Record/DEBITNO)
    ]"
    use="generate-id()"/>

  <xsl:key name="k2" match="DataPage[
    preceding-sibling::DataPage/Record/DEBITNO = Record/DEBITNO]"
    use="generate-id(preceding-sibling::DataPage[
      Record/DEBITNO= current()/Record/DEBITNO
    ][last()])" />
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="DataPage"/>
  <xsl:template match="DataPage[key('k1',generate-id())]">
    <xsl:copy>
      <Record>
        <xsl:apply-templates select="Record/TEMP
          |Record/DEBITNO
          |Record/DOSSIERNUMMERINT"/>
        <xsl:for-each select=".|key('k2',generate-id())">
          <Line>
            <xsl:apply-templates select="Record/ID
              |Record/DATE
              |Record/YEAR
              |Record/DESC
              |Record/AMOUNT"/>
          </Line>
        </xsl:for-each>
        <xsl:apply-templates select="Record/HEAD"/>
      </Record>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

注意:有些XSLT处理程序似乎不支持在current()定义中使用k2函数。

如果您只想要一个更简单的解决方案(不支持本地分组),可以使用这个类似于Muenchian的方法

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
  <xsl:key name ="k" match="DataPage"
    use="Record/DEBITNO"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="DataPage"/>
  <xsl:template match="DataPage[ 
    generate-id() = generate-id(key('k', Record/DEBITNO)[1])
  ]">
    <xsl:copy>
      <Record>
        <xsl:apply-templates select="Record/TEMP
          |Record/DEBITNO
          |Record/DOSSIERNUMMERINT"/>
        <xsl:for-each select="key('k', Record/DEBITNO)">
          <Line>
            <xsl:apply-templates select="Record/ID
              |Record/DATE
              |Record/YEAR
              |Record/DESC
              |Record/AMOUNT"/>
          </Line>
        </xsl:for-each>
        <xsl:apply-templates select="Record/HEAD"/>
      </Record>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

在XSLT1.0中,这是一种众所周知的方法,即Muenchian法

我给自己写了一篇关于这件事的论文,还有一些细微的变化。你也可以找到它这里

票数 0
EN

Stack Overflow用户

发布于 2013-08-27 13:59:34

这是一个标准分组问题。在XSLT2.0中:

代码语言:javascript
复制
<xsl:template match="Root">
 <xsl:for-each-group select="DataPage/Record" group-by="DEBITNO">
  <DataPage>
    <Record>
     <xsl:copy-of select="TEMP, DEBITNO, DOSSIERNUMMERINT"/>
     <xsl:for-each select="current-group()">
       <Line>
         <xsl:copy-of select="ID, YEAR, DATE, DESC, AMOUNT"/>
       </
     </
   </
  </
 </
</   
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18466515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档