将 XML 文件转换为平面文件格式
Transforming XML File to Flat File Format
我正在寻找有关将 XML 文件转换为平面文件格式的其他参考资料,我已经看到了很多。我已经尝试了一些我在互联网上看到的代码,它有很大帮助。我尝试创建自己的 XSLT 文件,但无法在输出中获得我想要的内容。此外,我需要尽量减少 XSLT 中的编码,因为我要从 Header Record、Detail/Contra Record 和 Trailer 应用大量编码和条件。 header 记录的值是正确的,但是,当前输出的第 2 行和第 3 行不正确。我需要为每个交易填充应该有 1 个细节和 1 个反对。输出应该看起来像预期的输出。
谢谢。
样本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>
</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>
</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>
</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 和 0 和 17 是硬编码值。从下一行开始,很快,它只会重复这个过程,这次将从下一次出现的 Payment/Transaction.
中获取值
对于 Payment/Transaction 的每一次出现,它将创建 1 个详细记录和 1 个对比记录。在我的例子中,我有 4 个交易,输出应该有:
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
这是 fixed-length 格式。
试试这个作为你的起点:
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 </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 </xsl:text>
<!-- End of Contra Record -->
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
"contra" 记录还需要做更多的工作,但你还没有解释那部分。
注:
使用xpath-default-namespace
来处理您的输入使用的命名空间;
使用xsl:for-each
为每笔交易创建一条记录;
另请注意,当输出方法为文本时,使用 xsl:element
没有任何意义。
我正在寻找有关将 XML 文件转换为平面文件格式的其他参考资料,我已经看到了很多。我已经尝试了一些我在互联网上看到的代码,它有很大帮助。我尝试创建自己的 XSLT 文件,但无法在输出中获得我想要的内容。此外,我需要尽量减少 XSLT 中的编码,因为我要从 Header Record、Detail/Contra Record 和 Trailer 应用大量编码和条件。 header 记录的值是正确的,但是,当前输出的第 2 行和第 3 行不正确。我需要为每个交易填充应该有 1 个细节和 1 个反对。输出应该看起来像预期的输出。
谢谢。
样本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>
</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>
</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>
</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 和 0 和 17 是硬编码值。从下一行开始,很快,它只会重复这个过程,这次将从下一次出现的 Payment/Transaction.
中获取值对于 Payment/Transaction 的每一次出现,它将创建 1 个详细记录和 1 个对比记录。在我的例子中,我有 4 个交易,输出应该有:
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
这是 fixed-length 格式。
试试这个作为你的起点:
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 </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 </xsl:text>
<!-- End of Contra Record -->
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
"contra" 记录还需要做更多的工作,但你还没有解释那部分。
注:
使用
xpath-default-namespace
来处理您的输入使用的命名空间;使用
xsl:for-each
为每笔交易创建一条记录;
另请注意,当输出方法为文本时,使用 xsl:element
没有任何意义。