tags:

views:

3127

answers:

4

I've got an extremely long XML file, like

<Root>
   <ele1>
      <child1>context1</child1>
      <child2>test1</child2>
      <child1>context1</child1>
   </ele1>

   <ele2>
      <child1>context2</child1>
      <child2>test2</child2>
      <child1>context2</child1>
   </ele2>
   <ele3>...........<elen>
</Root>

Now I want to remove all the second <child1> in each <ele> using xslt, is it possible? The result would be like this:

<Root>
   <ele1>
      <child1>context1</child1>
      <child2>test1</child2>
   </ele1>

   <ele2>
      <child1>context2</child1>
      <child2>test2</child2>
   </ele2>
       <ele3>...........<elen>
</Root>

Thank u, BR

Allen

+1  A: 

Your xml and question are kind of unclear, but what you're looking for is commonly called the Muenchian Grouping method - it's another way of asking for distinct nodes. With the appropriate keys this can be done very efficiently.

annakata
This is more of a hint than an answer. People need serious and responsible responses.
Dimitre Novatchev
Demonstrate in what way this is irresponsible or trivial. Please provide a URL which clearly states that all answers on SO must be full and definitive, regardless of the quality of the question. Indicate what you hoped to achieve with your comments **months** after the question has been asked.
annakata
A: 

Sorry, i forgot the pre code of the two tags in my question... now may be clearer

+1  A: 

This question requires a little bit more detailed answer than just pointing to a good Muenchian Grouping source.

The reason is that the needed grouping requires to identify both the names of all children of an "ele[SomeString]" element and their parent. Such grouping requires to define a key that is uniquely defined by both unique sources, usually via concatenation.

This transformation:

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

 <xsl:key name="kElByName" match="*"
      use="concat(generate-id(..), '+',name())"/>

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

    <xsl:template match="*[starts-with(name(), 'ele')]">
      <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates select=
         "*[generate-id()
           =
            generate-id(key('kElByName',
                        concat(generate-id(..), '+',name())
                        )[1])
            ]"
         />
      </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

when applied on this XML document:

<Root>
    <ele1>
     <child1>context1</child1>
     <child2>test1</child2>
     <child1>context1</child1>
    </ele1>
    <ele2>
     <child1>context2</child1>
     <child2>test2</child2>
     <child1>context2</child1>
    </ele2>
    <ele3>
     <child2>context2</child2>
     <child2>test2</child2>
     <child1>context1</child1>
    </ele3>
</Root>

produces the wanted result:

<Root>
    <ele1>
     <child1>context1</child1>
     <child2>test1</child2>
    </ele1>
    <ele2>
     <child1>context2</child1>
     <child2>test2</child2>
    </ele2>
    <ele3>
     <child2>context2</child2>
     <child1>context1</child1>
    </ele3>
</Root>
Dimitre Novatchev
A: 

Finally, it works, thank s for all of your suggestions.

@Allen: You could have accepted an answer... Just click on the white checkmark
Dimitre Novatchev