使用xslt显示包含组的嵌套元素

时间:2016-10-19 14:08:24

标签: xslt

我在xml中有edi doc看起来像这样(这只是一个片段,实际的EDI在这篇文章的末尾)

<ediroot>
<interchange><sender><address Id="7817942742" Qual="12" /></sender>
<group>
    <transaction Control="0001">
            <segment Id="B3">
                <element Id="B302">12345678</element>
                <element Id="B303">NS</element>
                <element Id="B304">CC</element>
                <element Id="B305">L</element>
            </segment>
            <segment Id="G62">
                <element Id="G6201">12</element>
                <element Id="G6202">20160928</element>
            </segment>
            <segment Id="R3">
                <element Id="R301">ABCD</element>
                <element Id="R302">B</element>
            </segment>
        </transaction>
        <transaction Control="0002">
            <segment Id="B3">
                <element Id="B302">999999</element>
                <element Id="B303">NS</element>
                <element Id="B304">CC</element>
            </segment>
            <segment Id="G62">
                <element Id="G6201">13</element>
                <element Id="G6202">20150928</element>
            </segment>
            <segment Id="R3">
                <element Id="R301">ABCD</element>
                <element Id="R302">B</element>
            </segment>
        </transaction>
    </group>
</interchange>
</ediroot>

我需要将元素Id设置为新元素,将元素值设置为值,如此

<ediroot>
<interchange>
<group>
    <transaction Control="0001">
            <B3>
                <B302>12345678</B302>
                <B303>NS</B303>
.....

我正在通过群体进行迭代,我正在使用这个xslt

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="ediroot">
<ediroot>
    <xsl:apply-templates select="interchange"/>
</ediroot>
</xsl:template>
    <xsl:template match="group">
        <transaction> 
            <xsl:apply-templates select="transaction"/>
        </transaction>
    </xsl:template>
            <xsl:template match="transaction">
            <txn>
                <xsl:for-each-group select="segment" group-by="@Id">
                    <group name="{current-grouping-key()}">
                        <Id><xsl:value-of select="element/@Id"/></Id>
                        <Value><xsl:value-of select="element"/></Value>
                    </group>
                </xsl:for-each-group>
            </txn>
            </xsl:template>

</xsl:stylesheet>

它会生成像这样的xml

<?xml version="1.0" encoding="UTF-8"?>
<ediroot>
   <transaction>
      <txn>
        <group name="B3">
            <Id>B302 B303 B304 B305</Id>
            <Value>12345678 NS CC L</Value>
        </group>

        <group name="G62">
            <Id>G6201 G6202</Id>
            <Value>86 20160928</Value>
        </group>
        <group name="R3">
            <Id>R301 R302</Id>
            <Value>ABCD B</Value>
        </group>
      </txn>
      <txn>
         <!-- second txn group -->
      </txn>
   </transaction>
</ediroot>

如何将group / transaction / segment / element作为单独的xml元素而不是一个节点?即而不是这个

<group name="B3">
            <Id>B302 B303 B304 B305</Id>
            <Value>12345678 NS CC L</Value>
        </group>

I need this

            <B3>
                <B302>12345678</B302>
                <B303>NS</B303>
                <B304>CC</B304>
                <B305>L</B305>

对于有兴趣查看实际xml的人,使用http://edireader.sourceforge.net/进行edi-to-xml转换

<?xml version="1.0" encoding="UTF-8"?>
<ediroot>
    <interchange Standard="ANSI X.12" Date="110813" Time="1410" StandardsId="U" Version="00300"
        Control="000000001">
        <sender>
            <address Id="ABCCOM         " Qual="01"/>
        </sender>
        <receiver>
            <address Id="999999999" Qual="01"/>
        </receiver>
        <group GroupType="IM" ApplSender="006998397" ApplReceiver="123456789" Date="20110813"
            Time="1410" Control="000000001" StandardCode="X" StandardVersion="004010">
            <transaction DocType="210" Name="Motor Carrier Freight Details and Invoice"
                Control="000000001">
                <segment Id="B3">
                    <element Id="B302">2509121213</element>
                    <element Id="B303">8000281336</element>
                    <element Id="B304">PP</element>
                    <element Id="B306">20110813</element>
                    <element Id="B307">18304</element>
                    <element Id="B309">20110801</element>
                    <element Id="B310">017</element>
                    <element Id="B311">XXXX</element>
                </segment>
                <segment Id="N9">
                    <element Id="N901">PO</element>
                    <element Id="N902">SM12003301</element>
                </segment>
                <segment Id="G62">
                    <element Id="G6201">86</element>
                    <element Id="G6202">20110801</element>
                </segment>
                <loop Id="N1">
                    <segment Id="N1">
                        <element Id="N101">CN</element>
                        <element Id="N102">AAA HARDWARE</element>
                    </segment>
                    <segment Id="N3">
                        <element Id="N301">9805 POPLAR ST</element>
                    </segment>
                    <segment Id="N4">
                        <element Id="N401">LEADVILLE</element>
                        <element Id="N402">CO</element>
                        <element Id="N403">80461</element>
                    </segment>
                </loop>
                <loop Id="N1">
                    <segment Id="N1">
                        <element Id="N101">SH</element>
                        <element Id="N102">BBB OIL COMPANY</element>
                    </segment>
                    <segment Id="N3">
                        <element Id="N301">2361 S DIXIE HWY</element>
                    </segment>
                    <segment Id="N4">
                        <element Id="N401">LIMA</element>
                        <element Id="N402">OH</element>
                        <element Id="N403">45802</element>
                    </segment>
                </loop>
                <loop Id="N1">
                    <segment Id="N1">
                        <element Id="N101">BT</element>
                        <element Id="N102">ANY PAY AGENT</element>
                    </segment>
                    <segment Id="N3">
                        <element Id="N301">ATTN: DONNA SMITH</element>
                        <element Id="N302">PO BOX 16789</element>
                    </segment>
                    <segment Id="N4">
                        <element Id="N401">ANYTOWN</element>
                        <element Id="N402">MO</element>
                        <element Id="N403">12345-6789</element>
                    </segment>
                </loop>
                <loop Id="LX">
                    <segment Id="LX">
                        <element Id="LX01">1</element>
                    </segment>
                    <segment Id="L5">
                        <element Id="L501">1</element>
                        <element Id="L502">PETROLEUM OILS,</element>
                        <element Id="L503">15525002</element>
                        <element Id="L504">N</element>
                    </segment>
                    <segment Id="L0">
                        <element Id="L001">1</element>
                        <element Id="L004">138</element>
                        <element Id="L005">N</element>
                        <element Id="L008">1</element>
                        <element Id="L009">PLT</element>
                        <element Id="L011">L</element>
                    </segment>
                    <segment Id="L1">
                        <element Id="L101">1</element>
                        <element Id="L102">120</element>
                        <element Id="L103">PH</element>
                        <element Id="L104">18304</element>
                    </segment>
                    <segment Id="L7">
                        <element Id="L701">1</element>
                        <element Id="L707">0E60</element>
                    </segment>
                </loop>
                <loop Id="LX">
                    <segment Id="LX">
                        <element Id="LX01">2</element>
                    </segment>
                </loop>
                <segment Id="L3">
                    <element Id="L301">138</element>
                    <element Id="L302">G</element>
                    <element Id="L305">18304</element>
                    <element Id="L311">1</element>
                </segment>
            </transaction>
        </group>
    </interchange>
</ediroot>

2 个答案:

答案 0 :(得分:1)

您提供的XML包含语法错误:它包含第二个<group>开始标记,其中需要结束标记。

虽然XSLT支持迭代,但通常有更简单的方法。你的似乎就是这种情况。您希望将具有Id属性的每个元素转换为另一个元素,这似乎需要一个带有适当选择器的简单模板,仅此而已。例如:

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <!-- identity transform for otherwise-unmatched nodes and attributes -->
   <xsl:template match="@*|node()">
     <xsl:copy>
       <xsl:apply-templates select="@*|node()" />
     </xsl:copy>
   </xsl:template>

   <!-- Special handling for elements bearing an Id attribute -->
   <xsl:template match="segment[@Id]|element[@Id]">
     <!-- transform as an element whose name is drawn from the Id attribute -->
     <xsl:element name="{@Id}">
       <!-- transform child nodes (including text nodes), but not attributes -->
       <xsl:apply-templates select="node()" />
     </xsl:element>
   </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

我不明白你的榜样。通常,您可以使用

<xsl:for-each select="current-group()"> 

或:

<xsl:apply-templates select="current-group()"/> 

处理当前组的成员。

工作示例:http://xsltransform.net/jz1PuP9