平面 xml 到具有额外内容的分层 xml

flat xml to hierarchial xml with extra content

我只是xslt领域的新手。由于我正在努力完成以下工作,所以我希望有人能帮助我解决这个问题。

我有一个平面输入 xml 文件,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<data>
   <Date>31-07-2016</Date>
   <Document_Date>31-07-2016</Document_Date>
   <ReportDate>31-07-2016</ReportDate>
   <Description>Some description</Description>
   <GLAccount_code>1234</GLAccount_code>
   <Costcenter_code>ALG</Costcenter_code>
   <Debtor_code>123456</Debtor_code>
   <Project_code>123456789</Project_code>
   <Currency_Code>EUR</Currency_Code>
   <Debit>0</Debit>
   <Credit>234.561386342626</Credit>
   <FreeText_number>WIP</FreeText_number>
 <!-- notice that here starts A new Date  (this repeats about 50 times with other data) -->
   <Date>31-07-2016</Date>
   <Document_Date>31-07-2016</Document_Date>
 <!-- and so on like above till FreeText_number -->
   <FreeText_number>WIP</FreeText_number>
</data>

我想要的 XML 输出应该是这样的:

<FinEntries>
    <FinEntry entry="20160804">
        <Division code="010" />
        <FinPeriod number="8"/>
        <Journal code="8600" type="M">
            <Journal_Description>Memoriaal OHW</Journal_Description>
        </Journal>
        <FinEntryLine number="1" type="N" subtype="N" code="   2" linecode="B" transactiontype="100">
            <Date>2016-07-31</Date>   <!-- Should come from data/Date -->
            <FinReferences TransactionOrigin="N">
                <DocumentDate>2016-07-31</DocumentDate> <!-- Should come from data/
                <ReportDate>2016-07-31</ReportDate>  <!-- Should come from data/ReportDate -->
            </FinReferences>    
            <GLAccount code="8090"> <!--Should come from GLAccount_code-->
            </GLAccount>
            <Description>OHW: WIP Change</Description>

            <Costcenter code="ALG">
            </Costcenter> <!-- Should come from Costcenter_code -->

            <Debtor code="9904" number = "9904" type="C">   <!-- Should come from Debtor_code -->

            </Debtor>
            <Project code="2550661-2" type="I" status="A"> <!-- Should come from Project_code (only the code ofcourse) -->
            </Project>
            <Amount>
                <Currency code="EUR"/>EUR</curremcy>   <!-- Should come from Currency_Code --> 
                <Debit>0</Debit>  <!-- Should come from Debit -->
                <Credit>-0.01</Credit> <!--Should come from Credit -->
            </Amount>
            <FreeFields>
                <FreeTexts>
                    <FreeText number="1">WIP</FreeText>  <!-- should come from FreeText_number -->
                </FreeTexts>
            </FreeFields>
        </FinEntryLine>

<!-- From here it will start a new FinEntryLine using the next set of data of the input xml again starting with a FinEntryLine-->
        <FinEntryLine number="1" type="N" subtype="N" code="   2" linecode="B" transactiontype="100">
            <Date>2016-07-31</Date>
<!-- and so on till it covered the whole input xml-->
    </FinEntry>
</FinEtnries>

我尝试了几天来完成这项工作,但我似乎没有让我的 xslt 按我的意愿工作。这就是我现在拥有的:

     <FinEntries>
       <FinEntry entry="20163107">
       <Division code="010"></Division>
       <FinYear number="2016"></FinYear>
       <FinPeriod number="7"></FinPeriod>
       <Journal code="86" type="M">
         <Description>Memoriaal OHW</Description>
       </Journal>
       <Amount>
         <Currency code="EUR"></Currency>
       </Amount>
                     <xsl:copy>
              <FinEntryLine number="1" type="N" subtype="N" code="   2" linecode="B" transactiontype="100">
                 <xsl:apply-templates select="/*" />  
              </FinEntryLine>
                     </xsl:copy>
         </FinEntry>
     </FinEntries>



 </xsl:template>

       <xsl:template match="Date">
         <date>
           <xsl:value-of select="."/>
         </date>
       </xsl:template>

       <xsl:template match="Document_Date">
         <FinReferences TransactionOrigin="N">
         <DocumentDate>
           <xsl:value-of select="."/>
         </DocumentDate>
         <ReportDate>
           <xsl:value-of select="."/>
         </ReportDate>    
         </FinReferences>             
       </xsl:template>

       <xsl:template match="GLAccount_code">
          <xsl:element name="GLAccount">
             <xsl:attribute name="code"><xsl:value-of select="."/></xsl:attribute>
          </xsl:element>
       </xsl:template>

       <xsl:template match="Description">
         <Description>
           <xsl:value-of select="."/>
         </Description>
       </xsl:template>

       <xsl:template match="Costcenter_code">
          <xsl:element name="Costcenter">
             <xsl:attribute name="code"><xsl:value-of select="."/></xsl:attribute>
          </xsl:element>
       </xsl:template>

       <xsl:template match="Debtor_code">
          <xsl:element name="Debtor">
             <xsl:attribute name="code"><xsl:value-of select="."/></xsl:attribute>
             <xsl:attribute name="number">Some number</xsl:attribute>
             <xsl:attribute name="type">Some type</xsl:attribute>
          </xsl:element>
       </xsl:template>

       <xsl:template match="Project_code">
          <xsl:element name="Project">
             <xsl:attribute name="code"><xsl:value-of select="."/></xsl:attribute>
             <xsl:attribute name="type">Some type</xsl:attribute>
             <xsl:attribute name="status">Some status</xsl:attribute>
          </xsl:element>
       </xsl:template>

       <xsl:template match="Currency_Code or Debit or Credit">
          <xsl:element name="Amount">
             <xsl:element name="Currency"> <xsl:value-of select="Currency_Code"/>
             </xsl:element>
             <xsl:element name="Debit"> <xsl:value-of select="Debit"/>
             </xsl:element>
             <xsl:element name="Credit"> <xsl:value-of select="Credit"/>
             </xsl:element>            
          </xsl:element>
       </xsl:template>

       <xsl:template match="FreeText_number">
          <xsl:element name="FreeFields">
             <xsl:element name="FreeTexts"> 
               <xsl:element name="FreeText">
               <xsl:attribute name="number"><xsl:value-of select="."/></xsl:attribute>
               </xsl:element>
             </xsl:element>            
          </xsl:element>
       </xsl:template>

 </xsl:stylesheet>      

结果中缺失:

附加信息:我的处理器无法处理 xslt 2.0

非常感谢您。 我希望有人有时间帮助我解决这个问题(也许再见甚至告诉我我做错了什么)。

为了尽量减少将元素分组的问题,每个组都以 Date 元素开头,请考虑以下样式表:

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="grp" match="*[not(self::Date)]" use="generate-id(preceding-sibling::Date[1])" />

<xsl:template match="/data">
    <FinEntry>
        <Division/>
        <FinPeriod/>
        <Journal>
            <Journal_Description></Journal_Description>
        </Journal>
        <FinEntries>
            <xsl:for-each select="Date">
                <FinEntryLine>
                    <Date>
                        <xsl:value-of select="."/>
                    </Date>
                    <xsl:apply-templates select="key('grp', generate-id())" /> 
                </FinEntryLine>
            </xsl:for-each>
        </FinEntries>
    </FinEntry>
</xsl:template>

<!-- add more templates here -->

</xsl:stylesheet>