使用XSLT合并两个或多个XML节点

时间:2012-04-29 00:59:11

标签: xml xslt

这是输入文件:

<root> 
    <node id="N1">
        <fruit id="1" action="aaa">
            <orange id="x" action="create">
                <attribute>
                    <color>Orange</color>
                    <year>2012</year>
                </attribute>
            </orange>
            <orange id="x" action="change">
                <attribute>
                    <color>Red</color>
                </attribute>
            </orange>
            <orange id="x" action="change">
                <attribute>
                    <color>Blue</color>
                    <condition>good</condition>
                </attribute>
            </orange>
        </fruit>

    </node>

    <node id="N2">
        <car id="1">    
            <bmw id="i" action="change">
                <attribute>
                    <color>Blue</color>    
                </attribute>
            </bmw>      
            <bmw id="i" action="change">
                <attribute>
                    <color>Yellow</color>    
                </attribute>
            </bmw>
            <bmw id="i" action="change">
                <attribute>
                    <color>Pink</color>    
                </attribute>
            </bmw>


        <bmw id="j" action="delete">
            <attribute>
                <color>Blue</color>    
            </attribute>
        </bmw>
        <bmw id="j" action="delete">
            <attribute>
                <color>Yellow</color>    
            </attribute>
        </bmw>

    </car>
    </node>
</root>

这是预期的输出:

<root> 
    <node id="N1">
        <fruit id="1" action="aaa">
            <orange id="x" action="create">
                <attribute>
                    <color>Blue</color>
                    <year>2012</year>
                    <condition>good</condition>
                </attribute>
            </orange>                      
        </fruit>       
    </node>

    <node id="N2">
        <car id="1">    

            <bmw id="i" action="change">
                <attribute>
                    <color>Pink</color>    
                </attribute>
            </bmw>


        <bmw id="j" action="delete">
            <attribute>
                <color>Yellow</color>    
            </attribute>
        </bmw>
      </car>
    </node>
</root>

规则:

  1. 如果存在带有'create'方法的节点,后跟一个或多个'change'方法,我们将它们合并在一起,并使用'create'方法将最后'change'中的所有子节点用于节点。 (注意:添加好)

  2. 如果有一个或多个'更改'方法,我们合并它们并仅使用上一个'更改'方法中的子项。

  3. 如果有一个或多个'删除'方法我们合并它们并且只使用上一个'删除'方法中的子项。

  4. 请注意,要合并的节点的id必须相同。

    请告诉我有关此问题的XSLT解决方案。 非常感谢。

    亲切的问候, 约翰

1 个答案:

答案 0 :(得分:2)

此转化

<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>

     <xsl:template match="node()|@*">
      <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
     </xsl:template>

     <xsl:template match="node/*/*[1]">
      <xsl:copy>
       <xsl:apply-templates select="@* | ../*[last()]/*"/>
      </xsl:copy>
     </xsl:template>

     <xsl:template match=
      "node/*/*
        [@action='delete'
       and
         following-sibling::*[1][@action='delete']
        ]"/>

     <xsl:template match=
      "node/*/*
        [@action='change'
       and
         following-sibling::*[1][@action='change']
       or
         preceding-sibling::*[@action='create']
        ]"/>
</xsl:stylesheet>

应用于提供的XML文档时:

<root>
    <node id="N1">
        <fruit id="1" action="aaa">
            <orange id="x" action="create">
                <attribute>
                    <color>Orange</color>
                </attribute>
            </orange>
            <orange id="x" action="change">
                <attribute>
                    <color>Red</color>
                </attribute>
            </orange>
            <orange id="x" action="change">
                <attribute>
                    <color>Blue</color>
                    <condition>good</condition>
                </attribute>
            </orange>
        </fruit>
    </node>
    <node id="N2">
        <car id="1">
            <bmw id="i" action="change">
                <attribute>
                    <color>Blue</color>
                </attribute>
            </bmw>
            <bmw id="i" action="change">
                <attribute>
                    <color>Yellow</color>
                </attribute>
            </bmw>
            <bmw id="i" action="change">
                <attribute>
                    <color>Pink</color>
                </attribute>
            </bmw>
            <bmw id="j" action="delete">
                <attribute>
                    <color>Blue</color>
                </attribute>
            </bmw>
            <bmw id="j" action="delete">
                <attribute>
                    <color>Yellow</color>
                </attribute>
            </bmw>
        </car>
    </node>
</root>

会产生想要的正确结果:

<root>
   <node id="N1">
      <fruit id="1" action="aaa">
         <orange id="x" action="create">
            <attribute>
               <color>Blue</color>
               <condition>good</condition>
            </attribute>
         </orange>
      </fruit>
   </node>
   <node id="N2">
      <car id="1">
         <bmw id="i" action="change">
            <attribute>
               <color>Pink</color>
            </attribute>
         </bmw>
         <bmw id="j" action="delete">
            <attribute>
               <color>Yellow</color>
            </attribute>
         </bmw>
      </car>
   </node>
</root>