0
votes

This is the input file:

<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>

This is the expected output:

<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>

The rule:

  1. if a node with the method 'destroy' appears at the end of the same parent (a fruit or an animal) we remove all the previous nodes.

  2. if NOT, we remove all the nodes including the one with 'destroy' method and leave the rest unchanged.

To simplify:

  • xxx/destroy -> destroy
  • xxx/destroy/aaa/bbb -> aaa/bbb

In summary we check the node that has the same id and node name (orange-id:1 or terrier-id:2 or poodle-id:1) and it must be under the same parent ex. (fruit or dog)

1
Seems like some necessary explanations are missing -- why there is an empty Toyota in the result?Dimitre Novatchev
@DimitreNovatchev because there is a prius id="x" action="create" and then prius id="x" action="destroy". As the rule suggested if destroy appears at the end we remove previous node, therefore only prius id="x" action="destroy" is kept (it is under the same parent toyota id=1). Hope it is clear.John
Sorry, it seems too complicated. Even the elements with the car-names are very confusing. Here we are dealing with XML and the car terminology is confusing. I really don't know whether series-x is another car or just version/modification of the same car. It is even possible that someone wouldn't know what bmw means -- we usually see this as BMW. The example is too long. Probably, if you split each individual case into a separate question and present a really short example, this would be better.Dimitre Novatchev
Even more confusing is why there occur two or more cars with the same id.Dimitre Novatchev
@DimitreNovatchev I have changed the example. I hope it will be clearer for you. If not I will separate the questions in two parts. Thanks very much for your time.John

1 Answers

1
votes

I couldn't quite match up your expected results, with how you described the rules you wanted. However, from comparing your expected output with the input, I think this is the condition you may need:

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

So, given the following 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>

When applied on your current input XML, the following is output, which matches you current expected output:

<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>