如何用XSLT将XML顶部位置信息复制到各交易明细节点?
将XML顶部位置信息批量添加到交易明细节点的XSLT方案
我有一份需转换后导入财务系统的XML文件,文件开头FacilityData节点下仅出现一次位置信息(包含Corp、FacilityID、CustomerLocationID等字段),后续是数百条transaction记录(已标记借方/贷方标识)。需要将顶部的位置信息提取并添加到每条交易记录的TransactionDetail节点下(部分交易有多条明细行,需作为独立行项目导入)。
源XML文件示例
<?xml version='1.0' encoding="UTF-8"?> <gldata> <FacilityData> <Corp>Fabrikam Group</Corp> <FacilityID>26</FacilityID> <CustomerLocationID>640</CustomerLocationID> <Region>PA</Region> <District>Springfield</District> <transaction> <EntryID>12345</EntryID> <TransactionDate>07-24-2023</TransactionDate> <ServiceDate> </ServiceDate> <TransactionType>40</TransactionType> <TransDescription>Desription Generic</TransDescription> <AccountNumber>1010-00</AccountNumber> <Currency>USD</Currency> <AccountType>A</AccountType> <BatchID>2351</BatchID> <TransactionDetail> <Amount>628.00</Amount> <Type>DRAmount</Type> </TransactionDetail> </transaction> </FacilityData> </gldata>
当前使用的XSLT代码
<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="*"/> <!-- identity transform --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="TransactionDetail"> <xsl:element name="{Type}"> <xsl:apply-templates/> </xsl:element> </xsl:template> </xsl:stylesheet>
期望输出效果
<transaction> <EntryID>12345</EntryID> <TransactionDate>07-24-2023</TransactionDate> <ServiceDate> </ServiceDate> <TransactionType>40</TransactionType> <TransDescription>Desription Generic</TransDescription> <AccountNumber>1010-00</AccountNumber> <Currency>USD</Currency> <AccountType>A</AccountType> <BatchID>2351</BatchID> <TransactionDetail> <Amount>628.00</Amount> <Type>DRAmount</Type> <CustomerLocationID>640</CustomerLocationID> </TransactionDetail> </transaction>
解决方案XSLT代码
<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="*"/> <!-- 预存顶部所有位置信息节点(排除transaction节点) --> <xsl:variable name="location-info" select="/gldata/FacilityData/*[not(self::transaction)]"/> <!-- 默认标识转换:原样复制所有节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 处理TransactionDetail节点:添加位置信息 --> <xsl:template match="TransactionDetail"> <xsl:copy> <!-- 保留原有明细内容 --> <xsl:apply-templates/> <!-- 复制所有位置信息节点到当前明细下 --> <xsl:copy-of select="$location-info"/> </xsl:copy> </xsl:template> <!-- 若只需添加特定字段(比如仅CustomerLocationID),替换上面的copy-of为: <xsl:copy-of select="$location-info/CustomerLocationID"/> --> </xsl:stylesheet>
关键说明
- 预存位置信息:用
<xsl:variable>提前抓取FacilityData下除transaction外的所有位置字段,避免重复查找。 - 保留原有结构:默认的标识转换模板确保大部分节点原样复制,不破坏原有交易数据结构。
- 批量注入明细:在
TransactionDetail的处理模板中,先保留原有明细内容,再将预存的位置信息批量复制到每个明细节点内。如需仅添加特定字段,修改copy-of的选择器即可。
内容的提问来源于stack exchange,提问作者Eric Waggoner
相关产品推荐
相关产品推荐

