XSLT 1.0多记录转单记录求助:自定义XSLT无法生成预期输出
需求与问题
输入XML:
<ns0:TestDTM xmlns:ns0="http://SchemaIN"> <ID>1234</ID> <Ref>A1</Ref> <Detail> <Qualifier>Q1</Qualifier> <Value>Name</Value> </Detail> <Detail> <Qualifier>Q2</Qualifier> <Value>Address</Value> </Detail> <Detail> <Qualifier>Q3</Qualifier> <Value>AddressType</Value> </Detail> </ns0:TestDTM>
预期输出(Header仅出现一次):
<ns0:Root xmlns:ns0="http://SchemaOUT"> <Header> <ID>1234</ID> <Ref>A1</Ref> <Value1>Name</Value1> <Value2>Address</Value2> <Value3>AddressType</Value3> </Header> </ns0:Root>
现有XSLT 1.0代码(无法生成预期输出):
<?xml version="1.0" encoding="UTF-16"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" version="1.0" xmlns:s0="http://SchemaIN" xmlns:ns0="http://SchemaOUT"> <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" /> <xsl:template match="/"> <xsl:apply-templates select="/s0:TestDTM" /> </xsl:template> <xsl:template match="/s0:TestDTM"> <ns0:Root> <xsl:for-each select="Detail"> <Header> <xsl:choose> <xsl:when test="Qualifier = 'Q1'"> <Value1> <xsl:value-of select="Value/text()" /> </Value1> </xsl:when> <xsl:when test="Qualifier = 'Q3'"> <Value2> <xsl:value-of select="Value/text()" /> </Value2> </xsl:when> </xsl:choose> </Header> </xsl:for-each> </ns0:Root> </xsl:template> </xsl:stylesheet>
问题分析
原代码的核心问题:
- 在
Detail节点的循环中每次都创建<Header>标签,导致输出多个Header,不符合要求 - 未处理输入中的
<ID>和<Ref>节点 - 匹配规则错误:Q2对应Value2、Q3对应Value3的逻辑缺失,原代码把Q3映射到了Value2
修正后的XSLT 1.0代码
<?xml version="1.0" encoding="UTF-16"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" version="1.0" xmlns:s0="http://SchemaIN" xmlns:ns0="http://SchemaOUT"> <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes"/> <xsl:template match="/"> <xsl:apply-templates select="/s0:TestDTM" /> </xsl:template> <xsl:template match="s0:TestDTM"> <ns0:Root> <!-- 仅创建一次Header节点 --> <Header> <!-- 复制ID和Ref节点 --> <xsl:copy-of select="ID | Ref"/> <!-- 根据Qualifier匹配生成对应的Value节点 --> <Value1> <xsl:value-of select="Detail[Qualifier='Q1']/Value"/> </Value1> <Value2> <xsl:value-of select="Detail[Qualifier='Q2']/Value"/> </Value2> <Value3> <xsl:value-of select="Detail[Qualifier='Q3']/Value"/> </Value3> </Header> </ns0:Root> </xsl:template> </xsl:stylesheet>
代码说明
- 移除原代码中对
Detail的循环,直接在TestDTM模板内创建唯一的<Header>节点 - 使用
<xsl:copy-of>直接复制输入中的<ID>和<Ref>节点,简化代码逻辑 - 通过
Detail[Qualifier='Qx']的谓词筛选,精准匹配每个Qualifier对应的Value值,生成对应的Value1/Value2/Value3节点 - 添加
indent="yes"让输出格式更整洁,与预期结构一致
内容的提问来源于stack exchange,提问作者sukra
相关产品推荐
相关产品推荐

