Tricky XSL transformation

J

jl

Hi everybody!

I have an interesting problem - and so far, I haven't been able to
solve it. Maybe somebody else has an idea...

I have a source xml structure that comes from a legacy system. It is
somewhat similar to a database structure:

<data>
<fieldnames>
<name>Column 1</name>
<name>Column 2</name>
...
</fieldnames>
<rows>
<row id="1">
<value>Value 1</value>
<value>Value 2</value>
...
</row>
<row id="2">
....
</row>
</rows>
</data>

This should be tranformed to a structure much like this:

<data>
<record id="1">
<col1>Value 1</col1>
<col2>Value 2</col2>
...
</record>
<record id="2">
...
</record>
</data>

All of this wouldn't be too hard if I could hard-code the respective
column indices, i.e. if 'Column 1' was alwas at position 1 etc. But
unfortunately that is not always the case - the columns can 'switch
places' - and therefore I cannot select <value> tags according to their
'position()'.

I am at a loss here - any ideas?

Thanks,

Joerg
 
A

Andy Dingley

jl said:
unfortunately that is not always the case - the columns can 'switch
places' - and therefore I cannot select <value> tags according to their
'position()'.

Select the <value> elements according to their position(), but
determine this position at the beginning of run-time, by evaluating the
position() of the appropriate "Column 1" element and storing this in an
XSLT variable, for each column.
 
J

jl

Andy said:
Select the <value> elements according to their position(), but
determine this position at the beginning of run-time, by evaluating the
position() of the appropriate "Column 1" element and storing this in an
XSLT variable, for each column.

Hi Andy!

Thank you for the idea! Do you have a coding sample? Because I have no
clue how to do that (in XSL).

Regards,

Joerg
 
A

Andy Dingley

jl said:
Thank you for the idea! Do you have a coding sample?

Here's some scruffy code for the much easier way to do it, which takes
its ordering from the data order rather than the columns. As any
downstream processing _ought_ to use the XML element names rather than
implicit position, then it'll probably work for you.

Taking the order from the columns is a bit harder! (I might have time
to hack it later)


<xsl:template match="/" >

<xsl:variable name="dataset" select="document('')//d:data" />
<xsl:variable name="columns" select="$dataset/d:fieldnames/d:name" />

<data>
<xsl:for-each select="$dataset/d:rows/d:row" >
<record>
<xsl:attribute name="id" ><xsl:value-of select="./@id"
/></xsl:attribute>

<xsl:for-each select="./d:value" >
<xsl:variable name="col-idx" select="position()" />
<xsl:variable name="column" select="$columns [position() =
$col-idx]" />
<xsl:variable name="column-name" select="translate
(normalize-space ($column/text()), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ',
'abcdefghijklmnopqrstuvwxyz-')" />

<xsl:element name="{$column-name}" ><xsl:apply-templates
/></xsl:element>
</xsl:for-each>

</record>
</xsl:for-each>
</data>

</xsl:template>
 

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

Forum statistics

Threads
474,005
Messages
2,570,264
Members
46,859
Latest member
HeidiAtkin

Latest Threads

Top