将XML文件转换为平面文件格式

时间:2016-12-16 05:55:28

标签: xslt xslt-2.0

我正在寻找关于将XML文件转换为平面文件格式的其他参考资料,我已经看过很多这些参考资料。我已经尝试了一些我在互联网上看到的代码并且它有很多帮助。我试着做我自己的XSLT文件,但我无法在输出中得到我想要的东西。另外,我需要最小化我在XSLT中的编码,因为我有很多编码和条件要应用于Header Record,Detail / Contra Record和Trailer。标题记录的值是正确的,但是,当前输出的第2行和第3行不正确。我需要为每个交易填充应该有1个细节和1个Contra。输出应该与预期输出的内容相似。

谢谢。

示例XML文件

<SyncCreditTransfer xmlns="http://schema.infor.com/InforOAGIS/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" releaseID="9.2" versionID="2.12.3" xsi:schemaLocation="http://schema.infor.com/InforOAGIS/2 http://schema.infor.com/2.12.x/InforOAGIS/BODs/SyncCreditTransfer.xsd">
<Application>
    <Sender>
        <LogicalID>company department</LogicalID>
    </Sender>
    <CreationDateTime>2016-07-01T05:50:16.208Z</CreationDateTime>
</Application>
<Data>
    <Sync>
        <ID>1122EDF6394</ID>
        <EntityID>SampleFiele</EntityID>
    </Sync>
    <Record>
        <Header>
            <DateTime>2016-07-01T05:51:16</DateTime>
        </Header>
        <Payment>
            <DisplayID>Payment1: 09459732</DisplayID>
            <DebtorParty>
                <FinancialAccount>
                    <ID>11111</ID>
                </FinancialAccount>
            </DebtorParty>
            <Transaction sequence="1">
                <TransactionID>BOA-t-121212</TransactionID>
                <InstructedAmount currencyID="EUR">123.43</InstructedAmount>
                <CreditorParty>
                    <FinancialAccount>
                        <ID>AAAAA</ID>
                    </FinancialAccount>
                </CreditorParty>
            </Transaction>
            <Transaction sequence="1">
                <TransactionID>BOA-t-343434</TransactionID>
                <InstructedAmount currencyID="GBP">123.43</InstructedAmount>
                <CreditorParty>
                    <FinancialAccount>
                        <ID>BBBBB</ID>
                    </FinancialAccount>
                </CreditorParty>
            </Transaction>
        </Payment>
        <Payment>
            <DisplayID>Payment2: 12435435</DisplayID>
            <DebtorParty>
                <FinancialAccount>
                    <ID>22222</ID>
                </FinancialAccount>
            </DebtorParty>
            <Transaction sequence="1">
                <TransactionID>BOA-t-090909</TransactionID>
                <InstructedAmount currencyID="EUR">123.43</InstructedAmount>
                <CreditorParty>
                    <FinancialAccount>
                        <ID>AAAAA</ID>
                    </FinancialAccount>
                </CreditorParty>
            </Transaction>
            <Transaction sequence="1">
                <TransactionID>BOA-t-878787</TransactionID>
                <InstructedAmount currencyID="GBP">123.43</InstructedAmount>
                <CreditorParty>
                    <FinancialAccount>
                        <ID>BBBBB</ID>
                    </FinancialAccount>
                </CreditorParty>
            </Transaction>
        </Payment>
    </Record>
</Data>

XSLT文件

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:func="myfunc">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:function name="func:trunc">
    <xsl:param name="str"/>
    <xsl:param name="len"/>
    <xsl:value-of select="substring($str,1,$len)"/>
</xsl:function>
<xsl:template match="/">
    <!-- Start of Header Record -->
    <xsl:element name="UserHeadLabel">
        <xsl:text>UHL</xsl:text>
    </xsl:element>
    <xsl:element name="Constant01">
        <xsl:text>1</xsl:text>
    </xsl:element>
    <xsl:element name="Filler01">
        <xsl:text> </xsl:text>
    </xsl:element>
    <xsl:element name="PaymentDate">
        <xsl:if test="//*:Header/*:DateTime[normalize-space()]!=''">
            <xsl:value-of select="func:trunc(//*:Header/*:DateTime,5)"/>
        </xsl:if>
    </xsl:element>
    <xsl:element name="Constant02">
        <xsl:text>999999</xsl:text>
    </xsl:element>
    <xsl:element name="Filler02">
        <xsl:text>    </xsl:text>
    </xsl:element>
    <xsl:element name="CurrencyCode">
        <xsl:choose>
            <xsl:when test="//*:Payment/*:Transaction/*:InstructedAmount/@currencyID[normalize-space()]!='' and //*:Payment/*:Transaction/*:InstructedAmount/@currencyID='EUR'">
                <xsl:text>01</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>00</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:element>
    <xsl:element name="Constant03">
        <xsl:text>000000</xsl:text>
    </xsl:element>
    <xsl:element name="Constant04">
        <xsl:text>1 DAILY  </xsl:text>
    </xsl:element>
    <xsl:element name="FileNumber">
        <xsl:text>001</xsl:text>
    </xsl:element>
    <xsl:element name="Filler03">
        <xsl:text>   </xsl:text>
    </xsl:element>
    <xsl:element name="Optional01">
        <xsl:text>       </xsl:text>
    </xsl:element>
    <xsl:element name="Optional02">
        <xsl:text>   </xsl:text>
    </xsl:element>
    <xsl:element name="UserOptional">
        <xsl:text>000000000000</xsl:text>
    </xsl:element>
    <xsl:text>&#xa;</xsl:text>
    <!-- End of Header Record -->

    <!-- Start of Detail Record -->
        <xsl:element name="DestinationSortCodeNo">
            <xsl:if test="//*:Payment/*:Transaction/*:CreditorParty/*:FinancialAccount/*:ID[normalize-space()]!=''">
                <xsl:value-of select="//*:Payment/*:Transaction/*:CreditorParty/*:FinancialAccount/*:ID"/>
            </xsl:if>
        </xsl:element>
        <xsl:element name="DestinationAccountNo">
            <xsl:if test="//*:Payment/*:Transaction/*:TransactionID[normalize-space()]!=''">
                <xsl:value-of select="//*:Payment/*:Transaction/*:TransactionID"/>
            </xsl:if>
        </xsl:element>
    <xsl:element name="Zero01">
        <xsl:text>0</xsl:text>
    </xsl:element>
    <xsl:element name="TransactionCode">
        <xsl:text>99</xsl:text>
    </xsl:element>
    <xsl:text>&#xa;</xsl:text>
    <!-- End of Detail Record -->

    <!-- Start of Contra Record -->
        <xsl:element name="UserSortCodeNo1">
            <xsl:if test="//*:Payment/*:DebtorParty/*:FinancialAccount/*:ID[normalize-space()]!=''">
                <xsl:value-of select="//*:Payment/*:DebtorParty/*:FinancialAccount/*:ID"/>
            </xsl:if>
        </xsl:element>
        <xsl:element name="UserAccountNo1">
            <xsl:if test="//*:Payment/*:DisplayID[normalize-space()]!=''">
                <xsl:value-of select="//*:Payment/*:DisplayID"/>
            </xsl:if>
        </xsl:element>
    <xsl:element name="Zero01">
        <xsl:text>0</xsl:text>
    </xsl:element>
    <xsl:element name="TransactionCode">
        <xsl:text>17</xsl:text>
    </xsl:element>
    <xsl:text>&#xa;</xsl:text>
    <!-- End of Contra Record -->
</xsl:template>

当前输出

UHL1 2016-999999    010000001 DAILY  001             000000000000
AAAAA BBBBB CCCCC DDDDDBOA-t-121212 BOA-t-343434 BOA-t-090909 BOA-t-878787099
11111 22222Payment1: 09459732 Payment2: 12435435017

预期输出

UHL1 2016-999999    010000001 DAILY  001             000000000000
AAAAAABOA-t-12099
11111MPayment1017
BBBBBMBOA-t-34099
11111MPayment1017
CCCCCMBOA-t-09099
22222MPayment2017
DDDDDMBOA-t-87099
22222MPayment2017

说明:值 AAAAAA 来自 Payment / Transaction / CreditorParty / FinancialAccount / ID ,且只能有6个字符。 BOA-t-12 来自 Payment / Transaction / TransactionID ,此字段应只有8个字符。 0 是硬编码值,以及值 99 。在下一行, 11111M 来自 Payment / DebtorParty / FinancialAccount / ID Payment1 来自 Payment / DisplayID < / em>和 0 17 是硬编码值。从下一行开始,很快,它只会重复这个过程,这次价值将从下一次付款/交易中获得。

对于每次付款/交易,它将创建1条详细记录和1条反对记录。在我的例子中,我有4个Transaction,输出应该有:

Detail - 1st occurrence of Transaction
Contra - 1st occurrence of Transaction
Detail - 2nd occurrence
Contra - 2nd occurrence
Detail - 3rd occurrence
Contra - 3rd occurrence
Detail - 4th occurrence
Contra - 4th occurrence

这是一种固定长度的格式。

1 个答案:

答案 0 :(得分:0)

以此为出发点:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://schema.infor.com/InforOAGIS/2">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/SyncCreditTransfer">
    <!-- Start of Header Record -->
        <!-- skipped for the purpose of this example -->
    <!-- End of Header Record -->
    <!-- Records -->
    <xsl:for-each select="Data/Record/Payment/Transaction">
        <!-- Start of Detail Record -->
        <xsl:value-of select="substring(CreditorParty/FinancialAccount/ID, 1 , 6)"/>
        <xsl:value-of select="substring(TransactionID, 1 , 8)"/>
        <xsl:text>099&#10;</xsl:text>
        <!-- End of Detail Record -->
        <!-- Start of Contra Record -->
        <xsl:value-of select="../DebtorParty/FinancialAccount/ID"/>
        <xsl:value-of select="../DisplayID"/>
        <xsl:text>017&#10;</xsl:text>
        <!-- End of Contra Record -->
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

这仍需要更多关于&#34;反对&#34;记录,但你没有解释那部分。

注意:

  • 使用xpath-default-namespace来处理输入使用的命名空间;

  • 使用xsl:for-each为每笔交易创建记录;

另请注意,当输出方法是文本时,使用xsl:element毫无意义。