2013-08-27 48 views
2

我有一個非常基本的XSLT知識,我目前正在努力實現某些東西,我仍然試圖弄清楚它是否可能。XSLT數據合併

可以是XSLT 1.0或2.0

基本上這是

<?xml version="1.0" encoding="windows-1252"?> 
<Root> 
    <DataPage> 
     <Record> 
      <TEMP>xxx</TEMP> 
      <DEBITNO>6250281</DEBITNO> 
      <DOSSIERNUMMERINT>2</DOSSIERNUMMERINT> 
      <ID>Z60</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>2</DOSSIERNUMMERINT> 
      <ID>Z70</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> 

謹以此輸出以下

<?xml version="1.0" encoding="windows-1252"?> 
<Root> 
    <DataPage> 
     <Record> 
      <TEMP>xxx</TEMP> 
      <DEBITNO>6250281</DEBITNO> 
      <DOSSIERNUMMERINT>2</DOSSIERNUMMERINT> 
      <Line> 
       <ID>Z60</ID> 
       <DATE>31/01/2013</DATE> 
       <YEAR>2006</YEAR> 
       <DESC>Test Item 1</DESC> 
       <AMOUNT>   38170.0000000</AMOUNT> 
      </Line> 
      <Line> 
       <ID>Z70</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> 

所以邏輯將是我的XML的結構合併具有相同DEBITNO的所有記錄。

爲合併的規則比ID,日期,年份,DESC和數量可以從1號外觀採取其他一切

ID,日期,年份,DESC和量需要被放入一個標籤,因此,如果有2條記錄具有相同的DEBITNO,則會有2個訂單項,如果有5個記錄具有相同的DEBITNO,則結果記錄將包含5個訂單項。

我希望這是有道理的。

是這樣的可能嗎?

Regards,

回答

0

與所有尊重凱先生關於不提供解決方案的決定,這一個在XSLT 1.0解決您的具體情況,也可以更一般的情況下,一個解決方案,你可以有一個multiroot幾個root元素和本地組需要

<?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處理器不支持k2定義

功能使用

如果你想只爲你的情況更爲簡單的解決方案(不支持本地組),您可以使用此Muenchian類似方法

<?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> 

在XSLT 1.0這是一個衆所周知的方法,該Muenchian method

我寫了一篇關於它和一些小的變化的文章。你也可以找到它here

+0

嗨全部 我沒有忘記這個主題,或只是採取答案,離開,我剛剛非常忙碌,仍然打算從兩個答覆測試和學習。 只要我的日程安排允許進行一些測試,我會盡快回復。 謝謝! – M3mPh1z

+0

這對我有用。 – M3mPh1z

1

這是一個標準的分組問題。在XSLT 2.0:

<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"/> 
     </ 
    </ 
    </ 
    </ 
</ 
</ 
+0

嗨邁克爾, 原諒我,就像我說的我對XSLT知識有限。 這個概念對我來說很有意義,但是把它放到一個實踐中並不是太多,我認爲這是給我一個想法,而不是一個實際的功能XSLT,我正在通過它來嘗試解決這個問題。 謝謝! – M3mPh1z

+0

正確,我的正常風格不是爲人們編寫程序,而是指向正確的方向並幫助他們掌握學習曲線。我強烈建議在您嘗試在生產代碼中使用它之前,在自己的書中閱讀關於xsl:for-each-group的內容。 –