平面 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 找到新的日期节点后,我的 FinEntryLine 不会停止并使用新的 FinEntryLine 重新开始。
- 货币、借方和贷方有缺失值,将借方和贷方的金额放在一起。
附加信息:我的处理器无法处理 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>
我只是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 找到新的日期节点后,我的 FinEntryLine 不会停止并使用新的 FinEntryLine 重新开始。
- 货币、借方和贷方有缺失值,将借方和贷方的金额放在一起。
附加信息:我的处理器无法处理 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>