请求开发XSLT实现基于序列的跨XML文件数据转换
跨XML文件的XSLT序列转换解决方案
问题说明
需基于两个XML文件(filea.xml、fileb.xml)实现数据转换,核心需求:
- 按映射规则将filea中的数字型
siteid/partNum替换为fileb中对应位置的实际值 - 按站点分组部件数据,并对部件排序
- 生成指定结构的目标XML
映射规则
- filea.xml中
siteid的数字值对应fileb.xml中<sites>元素的位置序号:- siteid=1 → 第1个
<sites>值:RSA00083 - siteid=2 → 第2个
<sites>值:RSA00034
- siteid=1 → 第1个
- filea.xml中
partNum的数字值对应fileb.xml中<partnumber>元素的位置序号:- partNum=1 → 第1个
<partnumber>值:000B96 - partNum=2 → 第2个
<partnumber>值:000B97
- partNum=1 → 第1个
源文件(修正语法错误后)
filea.xml
<Json> <site_req> <siteid>1</siteid> <quantityAvail>1</quantityAvail> <quantityMax>1</quantityMax> <partNum>1</partNum> <partRequested>1</partRequested> </site_req> <site_req> <siteid>1</siteid> <quantityAvail>2</quantityAvail> <quantityMax>2</quantityMax> <partNum>2</partNum> <partRequested>2</partRequested> </site_req> <site_req> <siteid>2</siteid> <quantityAvail>3</quantityAvail> <quantityMax>31</quantityMax> <partNum>2</partNum> <partRequested>3</partRequested> </site_req> </Json>
注:修正了原文件中标签闭合错误(
</FMI_INQUIRE_REQ>改为</site_req>、<partRequested<2改为<partRequested>2)
fileb.xml
<?xml version="1.0" encoding="UTF-8"?> <Json xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <method>inquire</method> <params> <control> <origin>Oracle</origin> <version>12.0</version> </control> <inquiry> <sites>RSA00083</sites> <sites>RSA00034</sites> <sites>RSA00033</sites> <parts> <partnumber>000B96</partnumber> <partnumberAssigner>TATA</partnumberAssigner> <partnumber>000B97</partnumber> <partnumberAssigner>TATA</partnumberAssigner> </parts> </inquiry> </params> </Json>
目标文件
<?xml version="1.0" encoding="utf-8"?> <result xsi:noNamespaceSchemaLocation="schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <siteList> <siteid>RSA00083</siteid> <partsList> <partnum>000B96</partnum> <partAssigner>TATA</partAssigner> <sequenceNumber>1</sequenceNumber> <quantityAvail>1</quantityAvail> <quantityMax>1</quantityMax> </partsList> <partsList> <partnum>000B97</partnum> <partAssigner>TATA</partAssigner> <sequenceNumber>2</sequenceNumber> <quantityAvail>2</quantityAvail> <quantityMax>2</quantityMax> </partsList> </siteList> <siteList> <siteid>RSA00034</siteid> <partsList> <partnum>000B97</partnum> <partAssigner>TATA</partAssigner> <sequenceNumber>3</sequenceNumber> <quantityAvail>3</quantityAvail> <quantityMax>31</quantityMax> </partsList> </siteList> <messages> <messageType>INFO</messageType> <messageCode>TATA001</messageCode> <messageVars/> <fieldName /> <app>Oracle Inventory</app> <module>Inv</module> <messageText>Information Received.</messageText> </messages> </result>
注:修正了目标文件中
<siteId>标签大小写不一致问题,统一为<siteid>
原代码问题分析
你编写的XSLT仅做了简单的标签复制/改名,未实现:
- 跨文件读取fileb.xml的映射数据
siteid/partNum与实际值的映射逻辑- 按站点分组、部件排序的核心需求
- 目标XML的结构生成
解决XSLT代码(XSLT 1.0)
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 定义键:按实际站点ID分组site_req --> <xsl:key name="site-group" match="site_req" use="document('fileb.xml')//sites[position() = current()/siteid]"/> <!-- 主模板:生成根元素result --> <xsl:template match="/"> <result xsi:noNamespaceSchemaLocation="schema.xsd"> <!-- 遍历所有唯一的站点分组 --> <xsl:for-each select="Json/site_req[generate-id() = generate-id(key('site-group', document('fileb.xml')//sites[position() = siteid])[1])]"> <xsl:variable name="current-site-id" select="document('fileb.xml')//sites[position() = siteid]"/> <siteList> <siteid><xsl:value-of select="$current-site-id"/></siteid> <!-- 对当前站点下的部件请求按partRequested排序 --> <xsl:for-each select="key('site-group', $current-site-id)"> <xsl:sort select="partRequested" data-type="number"/> <partsList> <!-- 映射partNum到实际部件编号 --> <xsl:if test="partNum"> <xsl:variable name="part-index" select="partNum"/> <partnum><xsl:value-of select="document('fileb.xml')//partnumber[$part-index]"/></partnum> <partAssigner><xsl:value-of select="document('fileb.xml')//partnumberAssigner[$part-index]"/></partAssigner> </xsl:if> <sequenceNumber><xsl:value-of select="partRequested"/></sequenceNumber> <quantityAvail><xsl:value-of select="quantityAvail"/></quantityAvail> <quantityMax><xsl:value-of select="quantityMax"/></quantityMax> </partsList> </xsl:for-each> </siteList> </xsl:for-each> <!-- 固定messages部分 --> <messages> <messageType>INFO</messageType> <messageCode>TATA001</messageCode> <messageVars/> <fieldName /> <app>Oracle Inventory</app> <module>Inv</module> <messageText>Information Received.</messageText> </messages> </result> </xsl:template> <!-- 忽略默认节点复制 --> <xsl:template match="@*|node()"/> </xsl:stylesheet>
关键逻辑说明
- 跨文件读取:使用
document('fileb.xml')加载外部XML文件,通过位置索引position()实现数字到实际值的映射 - 站点分组:用
<xsl:key>定义分组规则,按映射后的实际站点ID对site_req分组 - 排序处理:对每个站点下的
site_req按partRequested数值排序 - 结构生成:直接构建目标XML的层级结构,包含映射后的站点、部件信息,以及固定的messages模块
内容的提问来源于stack exchange,提问作者Curo
相关产品推荐
相关产品推荐

