Dipesh,
I have spent a little time with your problem and have something to get you
started up again....
I pretty much tossed your XSLT however, as it was pretty useless for
indicating what you want your results to be, and it's not in a coding style
that I can work with (it is highly "procedural" in nature, not a good fit
for XSLT). So I took your simplified input (thank you), and your desired
output, and implemented *part* of what I believe you want:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:e="http://exslt.org/common"
extension-element-prefixes="e">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="possible-headersRTF">
<xsl:for-each select="(//CLASS)[1]">
<!-- assumes all classes have similarly-structured ancestry -->
<xsl:for-each select="ancestor::*">
<field type="element">
<xsl:value-of select="generate-id()"/>
</field>
<xsl:for-each select="@*">
<!-- assumes attributes on ancestors, at least, are unique -->
<field type="attribute">
<xsl:value-of select="local-name()"/>
</field>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="//CLASS//Column">
<xsl:for-each select="@*">
<field type="attribute">
<xsl:value-of select="."/>
</field>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="possible-headers"
select="e:node-set($possible-headersRTF)"/>
<xsl:variable name="actual-headers"
select="$all-headers/*[not(.=preceding-sibling::*)]"/>
<xsl:template match="/">
<xsl:copy-of select="$actual-headers"/>
</xsl:template>
</xsl:stylesheet>
Running this on your source, I get:
<?xml version="1.0" encoding="utf-8"?>
<field type="element">d0e2</field>
<field type="attribute">Att1</field>
<field type="attribute">Att2</field>
<field type="element">d0e4</field>
<field type="attribute">Node1Att</field>
<field type="attribute">Node2Att</field>
<field type="attribute">ValOfColName1</field>
<field type="attribute">ValOfColName2</field>
<field type="attribute">ValOfColName3</field>
<field type="attribute">ValOfColName4</field>
<field type="attribute">ValOfColName5</field>
<field type="attribute">ValOfColName6</field>
... which, I believe, is a set of nodes that corresponds to the list of
headers you want.
Note it is not, itself, that list. For example, one will need to process
the field[@type='element'] nodes to get the labels that, apparently, you
want, which correspond (apparently) to element type names. But it has all
the information you need both to generate that list (that is, create your
header line), and to generate a line for each of your Columns that
enumerates all the values you want.
In order to get even this far, I had to use a couple of fairly
sophisticated techniques, including an extension function to convert the
results of my traversal of the source tree into a node set, so it could be
processed further -- this is how I removed duplicates from the list once I
had it.
Nonetheless, the *real* problem you are having is evidenced by the fact
that I could use neither your code, nor your problem description, to guide
me, but had to resort to making inferences based on the output you said you
wanted. In other words: the problem was *under-specified* -- and even
solving just the first part of it, I could have gone wrong simply by
mistaking what you wanted.
This is the level at which I think you need to be concentrating your
energies. Currently, you are trying to "think with your hands" by writing
code to approximate, successively, what you want. This is a perfectly
respectable technique, at times (I confess to using it myself, on occasion)
-- but it'll get you into trouble quickly if you are not perfectly familiar
with the processing model and best practices of the language you are using.
That is, when you are first learning. Which is what I believe is happening
to you.
Instead of trying to make it up as you go along, I'd recommend approaching
XSLT by putting together a complete specification of (a) inputs, (b)
outputs and (c) how outputs relate to inputs (*not* how they are created
procedurally but only how they are related), *before* you write a line of
code. Nowhere in your posts have I seen a really clear specification such
as, for example:
"First I need a header line that lists unique names of fields, delimited by `
characters, corresponding to:
* all ancestors of a CLASS
* all attributes on those ancestors
* all types of Column appearing in all CLASSES, distinguished by
values of ColName attributes
"Then, for each CLASS...."
Among the many reasons this is so important is that it provides the outline
of your stylesheet, and begins to break the problem up into manageable pieces.
Now you have -- maybe -- a partial solution for the first part of your
problem, I hope you can make headway. From here you could try either or
both of two things: 1. Apply the code I've written (assuming it's on the
right track), figuring out how it works and completing a solution based on
it; 2. Write up a complete specification of the problem and then code XSLT
to that.
Without a clear and complete problem specification, no one on the list can
really help you with the coding, since we don't know what to code. We can
guess, but that's not really all that much fun.
Good luck,
Wendell
======================================================================
Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc. http://www.mulberrytech.com
17 West Jefferson Street Direct Phone: 301/315-9635
Suite 207 Phone: 301/315-9631
Rockville, MD 20850 Fax: 301/315-8285
----------------------------------------------------------------------
Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list