XSL: need help with general * template

P

Piper707

I need help with using a general template which would process all tags
other than the ones for which specific templates have been written.

My XML looks like this:

<ITEMS>
<SPECIAL1>abc</SPECIAL1>
<SPECIAL2>abc</SPECIAL2>
...
<SPECIAL12>abc</SPECIAL9>
...
<KEY>0</KEY>
<KEY>1</KEY>
...
<OTHER1>xyz</OTHER1>
<OTHER2>xyz</OTHER2>
...
</ITEMS>
--------------------------------------

I need to convert to this format:

<elements>
//all SPECIAL tags are processed with a template correctly
<keys>
// all KEY tags processed with a template correctly
<keys>
//all tags other than the above mentioned need to be converted like
this.
<features>
<feature>
<name>other1</name>
<value>xyz</value>
</feature>
</feature>
<name>other2</name>
<value>xyz</value>
</feature>
</features>
</elements>
--------------------------------------

My xsl looks like this:

<xsl:template match="ITEMS">
<elements>
<xsl:apply-templates select="SPECIAL1" />
<xsl:apply-templates select="SPECIAL2" />
...
...
<xsl:if test="count(KEY) &gt; 0">
<keys>
<xsl:apply-templates select="KEY" />
</keys>
</xsl:if>

//WORKS FINE TILL THIS POINT

<features>
<xsl:apply-templates/>
</features>
</elements>
</xsl:template>

//TEMPLATES FOR SPECIAL1, SPECIAL2, KEY etc defined here

//general template definition
<xsl:template match="*">
<xsl:variable name="tag_value">
<xsl:value-of select="."/>
</xsl:variable>
<feature>
<name><xsl:value-of select="name(.)"/></name>
<value><xsl:value-of select="$tag_value"/></value>
</feature>
</xsl:template>

--------------------------------------

But this general template doesn't work. It gets invoked for all tags
regardless of the fact that they have their own templates defined.

I really need to figure out when I get a tag that is NOT SPECIAL1,
SPECIAL2...KEY then dump all those tags into a
<features></features> root tag in the new format.

How can I get the above behaviour?

Thanks for any help.
Rohit.
 
J

Janwillem Borleffs

But this general template doesn't work. It gets invoked for all tags
regardless of the fact that they have their own templates defined.

I really need to figure out when I get a tag that is NOT SPECIAL1,
SPECIAL2...KEY then dump all those tags into a
<features></features> root tag in the new format.

How can I get the above behaviour?

A simple fix would be to apply the "mode" attribute:

<features>
<xsl:apply-templates mode="other" />
</features>

....
<xsl:template match="*" mode="other">
...
</xsl:template>


HTH;
JW
 
P

Piper707

Hi Jan,

I tried what you suggested. I defined a general template of the form:

<xsl:template match="*" mode="other">
<feature>
<value><xsl:value-of select="."/></value>
</feature>
</xsl:template>

but i have the same problem again, the value for ALL the tags is caught
by the template, rather than only the ones without any template
definitions.

Someone had suggested using this approach:

*[not(self::X)][not(self::Y)][not(self::Z)]

but that would mean having to explicitly say "not the following tags" -
i wanted to avoid this approach, but if I have no other option, I would
like to know how I would define a template for this condition and how I
would call it?

is this the way to define it?

<xsl:template match="*[not(self::X)][not(self::Y)][not(self::Z)]">
</xsl:template>

and how do I call this?

<xsl:apply-templates
select="*[not(self::X)][not(self::Y)][not(self::Z)]" />

Thanks
Rohit.
 
J

Janwillem Borleffs

is this the way to define it?

<xsl:template match="*[not(self::X)][not(self::Y)][not(self::Z)]">
</xsl:template>

No, just match "*" as you did before.
and how do I call this?

<xsl:apply-templates
select="*[not(self::X)][not(self::Y)][not(self::Z)]" />

Correct. As an alternative, and when the SPECIAL* elements are always the
first two children, you could use:

<xsl:apply-templates select="*[position() &gt; 2]" />


JW
 
P

Piper707

Thanks jan. I'm now getting the behaviour that I was expecting.

I guess we need to be really careful when working with general
templates, they might not act like we expect them to!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top