XSLT将多个源元素映射到单个目标元素

时间:2016-03-06 08:58:40

标签: xslt xsd

我的要求是我有一个输入xml,其结构如下:

<Transaction-852>
<Loop-LIN>
        <Segment-LIN>
            <Element-350>001</Element-350>
            <Element-235>UP</Element-235>
            <Element-234>722868102237</Element-234>
            <Element-235_1>VP</Element-235_1>
            <Element-234_1>F2N036-06</Element-234_1>
        </Segment-LIN>
        <Loop-ZA>                                             
            <Segment-ZA>                                     
                <Element-859>QS</Element-859>
            </Segment-ZA>
            <Segment-SDQ>                                        
                <Element-355>EA</Element-355>                    
                <Element-66>92</Element-66>                      
                <Element-67>008</Element-67>                    
                <Element-380>1</Element-380>        
                <Element-67_1>018</Element-67_1>    
                <Element-380_1>1</Element-380_1>
                <Element-67_2>027</Element-67_2>
                <Element-380_2>1</Element-380_2>
                <Element-67_3>044</Element-67_3>
                <Element-380_3>-1</Element-380_3>
            </Segment-SDQ>
        </Loop-ZA>
    </Loop-LIN>
    <Loop-LIN>
        <Segment-LIN>
            <Element-350>002</Element-350>
            <Element-235>UP</Element-235>
            <Element-234>722868127469</Element-234>
            <Element-235_1>VP</Element-235_1>
            <Element-234_1>F2N025-10-GLD</Element-234_1>
        </Segment-LIN>
        <Loop-ZA>
            <Segment-ZA>
                <Element-859>QS</Element-859>
            </Segment-ZA>
            <Segment-SDQ>
                <Element-355>EA</Element-355>
                <Element-66>92</Element-66>
                <Element-67>007</Element-67>
                <Element-380>1</Element-380>
                <Element-67_1>010</Element-67_1>
                <Element-380_1>1</Element-380_1>
                <Element-67_2>017</Element-67_2>
                <Element-380_2>1</Element-380_2>
                <Element-67_3>020</Element-67_3>
                <Element-380_3>1</Element-380_3>
                <Element-67_4>021</Element-67_4>
                <Element-380_4>1</Element-380_4>
                <Element-67_5>022</Element-67_5>
                <Element-380_5>1</Element-380_5>
                <Element-67_6>025</Element-67_6>
                <Element-380_6>1</Element-380_6>
                <Element-67_7>028</Element-67_7>
                <Element-380_7>2</Element-380_7>
                <Element-67_8>048</Element-67_8>
                <Element-380_8>1</Element-380_8>
            </Segment-SDQ>
        </Loop-ZA>
    </Loop-LIN>
</Transaction-852>

输出XSD将为:

<xsd:complexType name="Record-Record1">
        <xsd:sequence>
            <xsd:element name="LIN-Element-350" type="xsd:string"/>
            <xsd:element name="LIN-Element-235" type="xsd:string"/>
            <xsd:element name="LIN-Element-234" type="xsd:string"/>
            <xsd:element name="LIN-Element-234_1" type="xsd:string"/>
            <xsd:element name="ZA-Element-859" type="xsd:string"/>
            <xsd:element name="SDQ-StoreNumber" type="xsd:string"/>
            <xsd:element name="SDQ-Qty" type="xsd:string"/>
        </xsd:sequence>
    </xsd:complexType>

SDQ段中的元素(((Element-67,Element-380)一组),((Element-67_1,Element-380_1)一组),((Element-67_2,Element-380_2))一组))Source中的元素应该与元素(SDQ-StoreNumber和SDQ-Qty)匹配,作为目标中的一组来显示以下输出。

我需要用o / p编写一个文件:

001 UP 722868102237 F2N036-06 QS 008 1 001 UP 722868102237 F2N036-06 QS 018 1 001 UP 722868102237 F2N036-06 QS 027 1 001 UP 722868102237 F2N036-06 QS 044 -1 002 UP 722868127469 F2N025-10-GLD QS 007 1 002 UP 722868127469 F2N025-10-GLD QS 010 1 002 UP 722868127469 F2N025-10-GLD QS 017 1 002 UP 722868127469 F2N025-10-GLD QS 020 1 002 UP 722868127469 F2N025-10-GLD QS 021 1 002 UP 722868127469 F2N025-10-GLD QS 022 1 002 UP 722868127469 F2N025-10-GLD QS 025 1 002 UP 722868127469 F2N025-10-GLD QS 028 1 002 UP 722868127469 F2N025-10-GLD QS 048 1

以XSD形式输出:

<Transaction-852>
    <LIN>
        <LIN-Element-350>001</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868102237</LIN-Element-234> 
        <LIN-Element-234_1>F2N036-06</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>008</SDQ-StoreNumber> 
        <SDQ-Qty>1</SDQ-Qty> 
    </LIN>
    <LIN>
        <LIN-Element-350>001</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868102237</LIN-Element-234> 
        <LIN-Element-234_1>F2N036-06</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>018</SDQ-StoreNumber> 
        <SDQ-Qty>1</SDQ-Qty> 
    </LIN>
    <LIN>
        <LIN-Element-350>001</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868102237</LIN-Element-234> 
        <LIN-Element-234_1>F2N036-06</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>027</SDQ-StoreNumber> 
        <SDQ-Qty>1</SDQ-Qty> 
    </LIN>
    <LIN>
        <LIN-Element-350>001</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868102237</LIN-Element-234> 
        <LIN-Element-234_1>F2N036-06</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>44</SDQ-StoreNumber> 
        <SDQ-Qty>-1</SDQ-Qty> 
    </LIN>
    <LIN>
        <LIN-Element-350>002</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868127469</LIN-Element-234> 
        <LIN-Element-234_1>F2N025-10-GLD</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>007</SDQ-StoreNumber> 
        <SDQ-Qty>1</SDQ-Qty> 
    </LIN>
    <LIN>
        <LIN-Element-350>002</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868127469</LIN-Element-234> 
        <LIN-Element-234_1>F2N025-10-GLD</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>010</SDQ-StoreNumber> 
        <SDQ-Qty>1</SDQ-Qty> 
    </LIN>
    <LIN>
        <LIN-Element-350>002</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868127469</LIN-Element-234> 
        <LIN-Element-234_1>F2N025-10-GLD</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>017</SDQ-StoreNumber> 
        <SDQ-Qty>1</SDQ-Qty> 
    </LIN>
    .
    .
    .
</Transaction-852>

请帮助我获取实现所需功能的代码。

由于

2016年3月7日更新:

最新来源xml:

<Transaction-852>
    <Segment-ST>
            <Element-143>852</Element-143>
            <Element-329>0001</Element-329>
        </Segment-ST>
        <Segment-XQ>
            <Element-305>H</Element-305>
            <Element-373>20140105</Element-373>
            <Element-373_1>20140111</Element-373_1>
        </Segment-XQ>
        <Loop-LIN>
            <Segment-LIN>
                <Element-350>001</Element-350>
                <Element-235>UP</Element-235>
                <Element-234>722868102237</Element-234>
                <Element-235_1>VP</Element-235_1>
                <Element-234_1>F2N036-06</Element-234_1>
            </Segment-LIN>
            <Loop-ZA>
                <Segment-ZA>
                    <Element-859>QS</Element-859>
                </Segment-ZA>
                <Segment-SDQ>
                    <Element-355>EA</Element-355>
                    <Element-66>92</Element-66>
                    <Element-67>008</Element-67>
                    <Element-380>1</Element-380>
                    <Element-67_1>018</Element-67_1>
                    <Element-380_1>1</Element-380_1>
                    <Element-67_2>027</Element-67_2>
                    <Element-380_2>1</Element-380_2>
                    <Element-67_3>044</Element-67_3>
                    <Element-380_3>-1</Element-380_3>
                </Segment-SDQ>
            </Loop-ZA>
        </Loop-LIN>
      <Loop-LIN>
        <Segment-LIN>
            <Element-350>002</Element-350>
            <Element-235>UP</Element-235>
            <Element-234>722868127469</Element-234>
            <Element-235_1>VP</Element-235_1>
            <Element-234_1>F2N025-10-GLD</Element-234_1>
        </Segment-LIN>
        <Loop-ZA>
            <Segment-ZA>
                <Element-859>QS</Element-859>
            </Segment-ZA>
            <Segment-SDQ>
                <Element-355>EA</Element-355>
                <Element-66>92</Element-66>
                <Element-67>007</Element-67>
                <Element-380>1</Element-380>
                <Element-67_1>010</Element-67_1>
                <Element-380_1>1</Element-380_1>
                <Element-67_2>017</Element-67_2>
                <Element-380_2>1</Element-380_2>
                <Element-67_3>020</Element-67_3>
                <Element-380_3>1</Element-380_3>
                <Element-67_4>021</Element-67_4>
                <Element-380_4>1</Element-380_4>
                <Element-67_5>022</Element-67_5>
                <Element-380_5>1</Element-380_5>
                <Element-67_6>025</Element-67_6>
                <Element-380_6>1</Element-380_6>
                <Element-67_7>028</Element-67_7>
                <Element-380_7>2</Element-380_7>
                <Element-67_8>048</Element-67_8>
                <Element-380_8>1</Element-380_8>
            </Segment-SDQ>
        </Loop-ZA>
    </Loop-LIN>
    .
    .
    . 
   <Segment-SE>
        <Element-96>1545</Element-96>
        <Element-329>0001</Element-329>
   </Segment-SE>
  </Transaction-852>

根据需要输出:

    <Transaction-852>
    <LIN>
        <LIN-Element-350>001</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868102237</LIN-Element-234> 
        <LIN-Element-234_1>F2N036-06</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>008</SDQ-StoreNumber> 
        <SDQ-Qty>1</SDQ-Qty> 
    </LIN>
    <LIN>
        <LIN-Element-350>001</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868102237</LIN-Element-234> 
        <LIN-Element-234_1>F2N036-06</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>018</SDQ-StoreNumber> 
        <SDQ-Qty>1</SDQ-Qty> 
    </LIN>
    <LIN>
        <LIN-Element-350>001</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868102237</LIN-Element-234> 
        <LIN-Element-234_1>F2N036-06</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>027</SDQ-StoreNumber> 
        <SDQ-Qty>1</SDQ-Qty> 
    </LIN>
    <LIN>
        <LIN-Element-350>001</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868102237</LIN-Element-234> 
        <LIN-Element-234_1>F2N036-06</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>44</SDQ-StoreNumber> 
        <SDQ-Qty>-1</SDQ-Qty> 
    </LIN>
    <LIN>
        <LIN-Element-350>002</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868127469</LIN-Element-234> 
        <LIN-Element-234_1>F2N025-10-GLD</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>007</SDQ-StoreNumber> 
        <SDQ-Qty>1</SDQ-Qty> 
    </LIN>
    <LIN>
        <LIN-Element-350>002</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868127469</LIN-Element-234> 
        <LIN-Element-234_1>F2N025-10-GLD</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>010</SDQ-StoreNumber> 
        <SDQ-Qty>1</SDQ-Qty> 
    </LIN>
    <LIN>
        <LIN-Element-350>002</LIN-Element-350>
        <LIN-Element-235>UP</LIN-Element-235>
        <LIN-Element-234>722868127469</LIN-Element-234> 
        <LIN-Element-234_1>F2N025-10-GLD</LIN-Element-234_1>
        <ZA-Element-859>QS</ZA-Element-859>
        <SDQ-StoreNumber>017</SDQ-StoreNumber> 
        <SDQ-Qty>1</SDQ-Qty> 
    </LIN>
    .
    .
    .
</Transaction-852>

使用现在的代码,它也考虑了<Segment-ST><Segment-XQ>,我得到的输出就像:

852 0001 H 20140105 20140111 001 UP 722868102237 VP F2N036-06 QS EA 92 008 1 018 1 027 1 044 -1 002 UP 722868127469 VP F2N025-10-GLD QS EA 92 007 1 010 1 017 1 020 1 021 1 022 1 025 1 028 2 048 1

由于

1 个答案:

答案 0 :(得分:0)

尝试以下方法,只需转换以Element-67开头的所有元素,然后创建相应的元素:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:output indent="yes"/>

    <xsl:template match="Transaction-852">
        <xsl:copy>
            <xsl:apply-templates select="//Segment-SDQ/*[starts-with(local-name(), 'Element-67')]"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Segment-SDQ/*[starts-with(local-name(), 'Element-67')]">
        <LIN>
            <xsl:copy-of select="ancestor::Loop-LIN/Segment-LIN/* | ancestor::Loop-ZA/Segment-ZA/Element-859"/>
            <SDQ-StoreNumber>
                <xsl:value-of select="."/>
            </SDQ-StoreNumber>
            <SDQ-Qty>
                <xsl:value-of select="following-sibling::*[starts-with(local-name(), 'Element-38')][1]"/>
            </SDQ-Qty>
        </LIN>
    </xsl:template>
</xsl:stylesheet>

我得到的结果是

<?xml version="1.0" encoding="utf-8"?>
<Transaction-852>
   <LIN>
      <Element-350>001</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868102237</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N036-06</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>008</SDQ-StoreNumber>
      <SDQ-Qty>1</SDQ-Qty>
   </LIN>
   <LIN>
      <Element-350>001</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868102237</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N036-06</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>018</SDQ-StoreNumber>
      <SDQ-Qty>1</SDQ-Qty>
   </LIN>
   <LIN>
      <Element-350>001</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868102237</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N036-06</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>027</SDQ-StoreNumber>
      <SDQ-Qty>1</SDQ-Qty>
   </LIN>
   <LIN>
      <Element-350>001</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868102237</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N036-06</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>044</SDQ-StoreNumber>
      <SDQ-Qty>-1</SDQ-Qty>
   </LIN>
   <LIN>
      <Element-350>002</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868127469</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N025-10-GLD</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>007</SDQ-StoreNumber>
      <SDQ-Qty>1</SDQ-Qty>
   </LIN>
   <LIN>
      <Element-350>002</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868127469</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N025-10-GLD</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>010</SDQ-StoreNumber>
      <SDQ-Qty>1</SDQ-Qty>
   </LIN>
   <LIN>
      <Element-350>002</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868127469</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N025-10-GLD</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>017</SDQ-StoreNumber>
      <SDQ-Qty>1</SDQ-Qty>
   </LIN>
   <LIN>
      <Element-350>002</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868127469</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N025-10-GLD</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>020</SDQ-StoreNumber>
      <SDQ-Qty>1</SDQ-Qty>
   </LIN>
   <LIN>
      <Element-350>002</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868127469</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N025-10-GLD</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>021</SDQ-StoreNumber>
      <SDQ-Qty>1</SDQ-Qty>
   </LIN>
   <LIN>
      <Element-350>002</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868127469</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N025-10-GLD</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>022</SDQ-StoreNumber>
      <SDQ-Qty>1</SDQ-Qty>
   </LIN>
   <LIN>
      <Element-350>002</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868127469</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N025-10-GLD</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>025</SDQ-StoreNumber>
      <SDQ-Qty>1</SDQ-Qty>
   </LIN>
   <LIN>
      <Element-350>002</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868127469</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N025-10-GLD</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>028</SDQ-StoreNumber>
      <SDQ-Qty>2</SDQ-Qty>
   </LIN>
   <LIN>
      <Element-350>002</Element-350>
      <Element-235>UP</Element-235>
      <Element-234>722868127469</Element-234>
      <Element-235_1>VP</Element-235_1>
      <Element-234_1>F2N025-10-GLD</Element-234_1>
      <Element-859>QS</Element-859>
      <SDQ-StoreNumber>048</SDQ-StoreNumber>
      <SDQ-Qty>1</SDQ-Qty>
   </LIN>
</Transaction-852>

关于有关不需要的行的注释,我在最新输出示例中看到的唯一区别是删除了Element-235_1元素,如果您不想要它们,您可以更改代码来执行此操作:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:output indent="yes"/>

    <xsl:template match="Transaction-852">
        <xsl:copy>
            <xsl:apply-templates select="//Segment-SDQ/*[starts-with(local-name(), 'Element-67')]"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Segment-SDQ/*[starts-with(local-name(), 'Element-67')]">
        <LIN>
            <xsl:copy-of select="ancestor::Loop-LIN/Segment-LIN/*[not(self::Element-235_1)] | ancestor::Loop-ZA/Segment-ZA/Element-859"/>
            <SDQ-StoreNumber>
                <xsl:value-of select="."/>
            </SDQ-StoreNumber>
            <SDQ-Qty>
                <xsl:value-of select="following-sibling::*[starts-with(local-name(), 'Element-38')][1]"/>
            </SDQ-Qty>
        </LIN>
    </xsl:template>

</xsl:stylesheet>