通过XSLT使用if-else条件简化xml节点

时间:2012-04-29 02:54:09

标签: xml xslt

这是输入文件:

<root> 
        <node id="N1">
            <fruit id="small_fruit" action="create">
                <orange id="1" action="create">
                    <attribute>
                        <color>yellow</color>
                    </attribute>
                </orange>
            </fruit>

            <fruit id="small_fruit" action="create">
                <orange id="1" action="destroy">
                    <attribute>
                        <color>green</color>
                    </attribute>
                </orange>
            </fruit>            
        </node>

        <node id="N2">
            <dog id="small_dog">    
                <poodle id="1" action="create">
                    <attribute>
                        <color>Yellow</color>    
                    </attribute>
                </poodle>       

                <terrier id="2" action="create">
                    <attribute>
                        <color>White</color>    
                    </attribute>
                </terrier>

                <poodle id="1" action="change">
                    <attribute>
                        <color>Brown</color>        
                    </attribute>
                </poodle>

                <terrier id="2" action="destroy">
                    <attribute>
                        <color>Blue</color>    
                    </attribute>
                </terrier>
            </dog>

            <dog id="small_dog" action="create">               
                <poodle id="1" action="destroy">
                    <attribute>
                        <color>Black</color>        
                    </attribute>
                </poodle>

                <terrier id="2" action="change">
                    <attribute>
                        <color>White</color>        
                    </attribute>
                </terrier>
                <terrier id="2" action="change">
                    <attribute>
                        <color>Grey</color>        
                    </attribute>
                </terrier>
            </dog>

            <dog id="large_dog">                
                <poodle id="1" action="create">
                    <attribute>
                        <color>Red</color>
                    </attribute>
                </poodle>
            </dog>
        </node>
    </root>

这是预期的输出:

<root> 
<node id="N1">
    <fruit id="small_fruit" action="create">

    </fruit>

    <fruit id="small_fruit" action="create">
        <orange id="1" action="destroy">
            <attribute>
                <color>green</color>
            </attribute>
        </orange>
    </fruit>            
</node>

<node id="N2">
    <dog id="small_dog">                           

    </dog>

    <dog id="small_dog" action="create">               
        <poodle id="1" action="destroy">
            <attribute>
                <color>Black</color>        
            </attribute>
        </poodle>

        <terrier id="2" action="change">
            <attribute>
                <color>White</color>        
            </attribute>
        </terrier>
        <terrier id="2" action="change">
            <attribute>
                <color>Grey</color>        
            </attribute>
        </terrier>
    </dog>

    <dog id="large_dog">                
        <poodle id="1" action="create">
            <attribute>
                <color>Red</color>
            </attribute>
        </poodle>
     </dog>
</node>
</root>

规则:

  1. 如果一个节点'destroy'的节点出现在同一个父节点(水果或动物)的末尾,我们会删除所有以前的节点。

  2. 如果不是,我们删除所有节点,包括带有'destroy'方法的节点,并保持其余节点不变。

  3. 简化:

    • xxx / destroy - &gt;毁灭
    • xxx / destroy / aaa / bbb - &gt; AAA / BBB

    总之,我们检查具有相同ID和节点名称的节点(orange-id:1或者terrier-id:2或poodle-id:1),它必须是同一父母前。 (水果或狗)

1 个答案:

答案 0 :(得分:1)

我无法完全符合您的预期结果,以及您如何描述您想要的规则。但是,通过比较您的预期输出和输入,我认为这是您可能需要的条件:

<xsl:if test="not(following::*[../@id = current()/../@id][@action='destroy'])">

因此,给出以下XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="node/*/*">
      <xsl:if test="not(following::*[../@id = current()/../@id][@action='destroy'])">
         <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
         </xsl:copy>
      </xsl:if>
   </xsl:template>

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

当应用于当前输入XML时,将输出以下内容,该内容与当前预期输出匹配:

<root>
   <node id="N1">
      <fruit id="small_fruit" action="create"/>
      <fruit id="small_fruit" action="create">
         <orange id="1" action="destroy">
            <attribute>
               <color>green</color>
            </attribute>
         </orange>
      </fruit>
   </node>
   <node id="N2">
      <dog id="small_dog"/>
      <dog id="small_dog" action="create">
         <poodle id="1" action="destroy">
            <attribute>
               <color>Black</color>
            </attribute>
         </poodle>
         <terrier id="2" action="change">
            <attribute>
               <color>White</color>
            </attribute>
         </terrier>
         <terrier id="2" action="change">
            <attribute>
               <color>Grey</color>
            </attribute>
         </terrier>
      </dog>
      <dog id="large_dog">
         <poodle id="1" action="create">
            <attribute>
               <color>Red</color>
            </attribute>
         </poodle>
      </dog>
   </node>
</root>