xsl-list
[Top] [All Lists]

Re: applying templates to all child elements except two specific ones

2002-12-06 00:54:18
--- Ram UGroups wrote:
 
Hello,

I do have an element in my input XML file which has a
nested structure with lots of other elements. If the
context element is called <element1>, I need to
process all the child elements of <element1> by
changing the case of their data, leaving two specific
child elements <child1> and <child2>.

Eg:

<someroot>
<element1>
<child1>first child<child1>
<name>
<firstname>John</firstname>
<lastname>Doe</lastname>
</name>
<address>
<street>555 First Stree</street>
<city>some city</city>
<state>some state</state>
<child2>random</child2>
</address>
</element1>
<otherelements/>
</someroot>

So data of all the elements between <element1> tags
should be changed to a different case except the data
in the elements <child1> and <child2>.

Any help would be appreciated.

Thanks.

The example provided is not a well-formed xml document. Also child2 is
not a child of element1.

Below is a solution to your problem, using the following modified
source.xml:
----------
<someroot>
  <element1>
    <child1>first child</child1>
    <name>
      <firstname>John</firstname>
      <lastname>Doe</lastname>
    </name>
    <address>
      <street>555 First Stree</street>
      <city>some city</city>
      <state>some state</state>
      <child2>random</child2>
    </address>
    <child2>of element1</child2>
  </element1>
  <otherelements/>
</someroot>


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

  <xsl:template match="@*|node()">  
    <xsl:copy>    
      <xsl:apply-templates select="@*|node()"/>  
    </xsl:copy>
  </xsl:template>  
  <xsl:template match="text()[normalize-space()]">
    X<xsl:value-of select="."/>
  </xsl:template>
  
  <xsl:template 
   match="text()[ancestor::child1[../self::element1]
               or
                 ancestor::child2[../self::element1]
                ]">
   Y<xsl:value-of select="."/>
  </xsl:template>
</xsl:stylesheet>

when applied to the source xml document above, this transformation
produces the following result:

<someroot>
  <element1>
    <child1>
   Yfirst child</child1>
    <name>
      <firstname>
    XJohn</firstname>
      <lastname>
    XDoe</lastname>
    </name>
    <address>
      <street>
    X555 First Stree</street>
      <city>
    Xsome city</city>
      <state>
    Xsome state</state>
      <child2>
    Xrandom</child2>
    </address>
    <child2>
   Yof element1</child2>
  </element1>
  <otherelements></otherelements>
</someroot>


This is essentially the identity transformation with an override for
text nodes, which have a "child1" or "child2" ancestor, whose parent is
"element1".

In case in the text of your message:
"
I need to
process all the child elements of <element1> by
changing the case of their data, leaving two specific
child elements <child1> and <child2>.
"

you meant not "child elements" but "descendent elements", then the
match of the overriding template should be changed to:

text()[ancestor::child1[ancestor::element1]
               or
                 ancestor::child2[ancestor::element1]
                ]">




=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list