XML Editor
Sign up for a WebBoard account Sign Up Keyword Search Search More Options... Options
Chat Rooms Chat Help Help News News Log in to WebBoard Log in Not Logged in
Show tree view Topic
Topic Page 1 2 3 4 5 6 7 8 9 Go to previous topicPrev TopicGo to next topicNext Topic
Postnext
Marek KucharikSubject: recursive copy tree with special change
Author: Marek Kucharik
Date: 02 Jan 2006 08:21 AM
Hello all,

I have I "little" problem.
I have XML like:
<?xml version="1.0" encoding="UTF-8"?>
<DISPLAY>
<BOARDS>
<row>
<column>&lt;boards xmlns="http://tempuri.org/NisaXMLSchema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tempuri.org/NisaXMLSchema.xsd NisaXMLSchema.xsd" version="1.0" &gt;</column>
<type>Nisa72x60</type>
<number>1</number>
<clear>true </clear>
</row>
</BOARDS>
<PLANE_1>
<row>
<rowOrder>18</rowOrder>
<column>&lt;code&gt;15196927&lt;/code&gt;&lt;hs column="10" /&gt;&lt;color val="yellow"&gt;&lt;hs column="20" /&gt;&lt;/color&gt;&lt;hs column="30" /&gt;&lt;blink&gt;Dec 29 2005 5:05PM&lt;/blink&gt;&lt;hs column="40" /&gt;&lt;bold&gt;&lt;code&gt;15196927_VASS&lt;/code&gt;&lt;/bold&gt;&lt;br/&gt;</column>
</row>
</PLANE_1>
<CODELIST>
<row>
<code>15196927</code>
<column>&lt;item&gt;OK0618&lt;/item&gt;</column>
</row>
<row>
<code>15196927_VASS</code>
<column>&lt;item&gt;VASS&lt;/item&gt;&lt;item&gt;SKBA&lt;/item&gt;&lt;item&gt;EGYP&lt;/item&gt;</column>
</row>
</CODELIST>
</DISPLAY>

and XSL transformation:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
<!-- set elements -->
<xsl:variable name="main_element">code</xsl:variable>
<xsl:variable name="sharecode_list">list</xsl:variable>
<!--<xsl:variable name="lister">list</xsl:variable>-->
<!-- set variables -->
<xsl:variable name="begin_element" select="concat('&lt;',$main_element,'&gt;')" />
<xsl:variable name="end_element" select="concat('&lt;/',$main_element,'&gt;')" />

<!-- get all values from codelist -->
<xsl:variable name="codelist" select="//CODELIST" />

<xsl:template match="DISPLAY">
<xsl:apply-templates select="BOARDS/*" />
<xsl:element name="board">
<xsl:attribute name="type"><xsl:value-of select="normalize-space(BOARDS/*[1]/type)" /></xsl:attribute>
<xsl:attribute name="number"><xsl:value-of select="normalize-space(BOARDS/*[1]/number)" /></xsl:attribute>
<xsl:attribute name="clear"><xsl:value-of select="if (string-length(BOARDS/*[1]/clear) > 0) then normalize-space(BOARDS/*[1]/clear) else 'false'" /></xsl:attribute>
<xsl:apply-templates select="TIME/*" /> <!-- time first! -->
<xsl:apply-templates select="DATE/*" /> <!-- date second! -->
<xsl:apply-templates select="node()[substring(local-name(), 1, 5) = 'PLANE'] "/> <!-- plane next! -->
<xsl:apply-templates select="RUNTEXT/*" /> <!-- running last! -->
</xsl:element>
<xsl:text disable-output-escaping="yes" >&lt;/boards&gt;</xsl:text>
</xsl:template>

<!-- DO OTHERS LIKE BOARDS, DATE... -->
<xsl:template match="BOARDS/* | DATE/* | TIME/* | RUNTEXT/*">
<xsl:value-of select="normalize-space(column)" disable-output-escaping="yes" />
</xsl:template>

<!-- DO PLANE! -->
<xsl:template match="*">
<xsl:element name="plane">
<xsl:attribute name="number"><xsl:value-of select="position()"/></xsl:attribute>
<xsl:for-each select="row/*[local-name() = 'column']">
<xsl:apply-templates select="." mode="codelist">
<xsl:with-param name="column" select="current()"></xsl:with-param>
</xsl:apply-templates>
</xsl:for-each>
</xsl:element>
</xsl:template>

<!-- CHOOSE RIGHT ONE FROM CODELIST -->
<xsl:template match="*" mode="list">
<xsl:element name="{$sharecode_list}">
<xsl:value-of select="column" disable-output-escaping="yes"/>
</xsl:element>
</xsl:template>

<!-- APPLY PLANE IN MODE CODELIST -->
<xsl:template match="*" mode="codelist" name="codelist">
<xsl:param name="column" />
<xsl:variable name="value" xmlns:saxon="http://saxon.sf.net/">
<xsl:copy-of select="saxon:parse(concat('&lt;root&gt;',$column,'&lt;/root&gt;'))"/>
</xsl:variable>
<xsl:for-each select="$value/root/*">
<xsl:choose>
<xsl:when test="local-name() = 'code'">
<!-- get value from codelist -->
<xsl:variable name="codevalue" select="." />
<xsl:apply-templates select="$codelist/*[code = $codevalue]" mode="list">
<xsl:with-param name="value" select="$codevalue" />
</xsl:apply-templates></xsl:when>
<xsl:when test="count(*) > 0">
<!-- go recursive -->
<xsl:call-template name="codelist">
<xsl:with-param name="column" select="." />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- copy all element with value -->
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>

</xsl:template>
</xsl:stylesheet>

and I need to copy all elements and from <PLANE_1> and find appropriate part from <CODELIST> for all <code>value</code>
My version "works" only when <code> is not a child element for another element.

Can you help me please?

Best regards,

Marek

Postnext
Minollo I.Subject: recursive copy tree with special change
Author: Minollo I.
Date: 02 Jan 2006 09:44 AM
>...
>...I need to copy all elements and from <PLANE_1> and find appropriate part from <CODELIST> for all <code>value</code>
>My version "works" only when <code> is not a child element for another element.

Which <code>? The one in the parsed $value? Maybe you can change the for loop to do:
<xsl:for-each select="$value/root//code">
...and abandon the recursive handling of that part? That would ensure you loop on all <code> elements, no matter at which level of the tree they are.

Minollo

Postnext
Marek KucharikSubject: recursive copy tree with special change
Author: Marek Kucharik
Date: 02 Jan 2006 09:49 AM
Hello Minollo,

yes, you're right, the one <code> which is parsed in value $value.

I've tried to go by that way but I need to copy all other elements which are not copied using $value/root//code

That's why I'm trying to use recursive code.

Marek

Postnext
Minollo I.Subject: recursive copy tree with special change
Author: Minollo I.
Date: 02 Jan 2006 09:58 AM
Maybe you can decouple the loop on <code>'s from the one copying the other elements? That way you could retrieve all the <code> elements at any level and still copy over all the other "top level" elements.

Minollo

Postnext
Marek KucharikSubject: recursive copy tree with special change
Author: Marek Kucharik
Date: 03 Jan 2006 04:40 AM
Hello Minollo,

I'm afraid I dont know what you mean :(
I found a problem in my transformation but there are still another problem when I'm using XML formated like this:
<blink><hs column="20" /><blink><hs column="20" /></blink></blink> which duplicates the part between first <blink>
At the time it's enough for me but for the future, may be you know how to solve it.

See input XML:
<?xml version="1.0" encoding="UTF-8"?>
<DISPLAY>
<BOARDS>
<row>
<column>&lt;boards xmlns="http://tempuri.org/NisaXMLSchema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tempuri.org/NisaXMLSchema.xsd NisaXMLSchema.xsd" version="1.0" &gt;</column>
<type>Nisa72x60</type>
<number>1</number>
<clear>true </clear>
</row>
</BOARDS>
<PLANE_1>
<row>
<rowOrder>18</rowOrder>
<column>&lt;hs column="10" /&gt;&lt;code&gt;15196927&lt;/code&gt;&lt;color val="yellow"&gt;&lt;blink&gt;&lt;hs column="30" /&gt;&lt;blink&gt;Dec 29 2005 5:05PM&lt;/blink&gt;&lt;/blink&gt;&lt;/color&gt;&lt;hs column="30" /&gt;&lt;blink&gt;Dec 29 2005 5:05PM&lt;/blink&gt;&lt;hs column="40" /&gt;&lt;bold&gt;&lt;code&gt;15196927_VASS&lt;/code&gt;&lt;/bold&gt;&lt;br/&gt;</column>
</row>
</PLANE_1>
<CODELIST>
<row>
<code>15196927</code>
<column>&lt;item&gt;OK0618&lt;/item&gt;</column>
</row>
<row>
<code>15196927_VASS</code>
<column>&lt;item&gt;VASS&lt;/item&gt;&lt;item&gt;SKBA&lt;/item&gt;&lt;item&gt;EGYP&lt;/item&gt;</column>
</row>
</CODELIST>
</DISPLAY>

and my XSLT:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
<!-- set elements -->
<xsl:variable name="main_element">code</xsl:variable>
<xsl:variable name="sharecode_list">list</xsl:variable>
<!--<xsl:variable name="lister">list</xsl:variable>-->
<!-- set variables -->
<xsl:variable name="begin_element" select="concat('&lt;',$main_element,'&gt;')" />
<xsl:variable name="end_element" select="concat('&lt;/',$main_element,'&gt;')" />

<!-- get all values from codelist -->
<xsl:variable name="codelist" select="//CODELIST" />

<xsl:template match="DISPLAY">
<xsl:apply-templates select="BOARDS/*" />
<xsl:element name="board">
<xsl:attribute name="type"><xsl:value-of select="normalize-space(BOARDS/*[1]/type)" /></xsl:attribute>
<xsl:attribute name="number"><xsl:value-of select="normalize-space(BOARDS/*[1]/number)" /></xsl:attribute>
<xsl:attribute name="clear"><xsl:value-of select="if (string-length(BOARDS/*[1]/clear) > 0) then normalize-space(BOARDS/*[1]/clear) else 'false'" /></xsl:attribute>
<xsl:apply-templates select="TIME/*" /> <!-- time first! -->
<xsl:apply-templates select="DATE/*" /> <!-- date second! -->
<xsl:apply-templates select="node()[substring(local-name(), 1, 5) = 'PLANE'] "/> <!-- plane next! -->
<xsl:apply-templates select="RUNTEXT/*" /> <!-- running last! -->
</xsl:element>
<xsl:text disable-output-escaping="yes" >&lt;/boards&gt;</xsl:text>
</xsl:template>

<!-- DO OTHERS LIKE BOARDS, DATE... -->
<xsl:template match="BOARDS/* | DATE/* | TIME/* | RUNTEXT/*">
<xsl:value-of select="normalize-space(column)" disable-output-escaping="yes" />
</xsl:template>

<!-- DO PLANE! -->
<xsl:template match="*">
<xsl:element name="plane">
<xsl:attribute name="number"><xsl:value-of select="position()"/></xsl:attribute>
<xsl:for-each select="row/*[local-name() = 'column']">
<xsl:apply-templates select="." mode="codelist">
<xsl:with-param name="column" select="current()" />
</xsl:apply-templates>
</xsl:for-each>
</xsl:element>
</xsl:template>

<!-- CHOOSE RIGHT ONE FROM CODELIST -->
<xsl:template match="*" mode="list">
<xsl:element name="{$sharecode_list}">
<xsl:value-of select="column" disable-output-escaping="yes"/>
</xsl:element>
</xsl:template>

<!-- APPLY PLANE IN MODE CODELIST -->
<xsl:template match="*" mode="codelist">
<xsl:param name="column" />
<xsl:variable name="value" xmlns:saxon="http://saxon.sf.net/">
<xsl:copy-of select="saxon:parse(concat('&lt;root&gt;',$column,'&lt;/root&gt;'))"/>
</xsl:variable>
<xsl:for-each select="$value/root/* | $column/* ">
<xsl:choose>
<xsl:when test="local-name() = 'code'">
<!-- get value from codelist -->
<xsl:variable name="codevalue" select="." />
<xsl:apply-templates select="$codelist/*[code = $codevalue]" mode="list">
<xsl:with-param name="value" select="$codevalue" />
</xsl:apply-templates>
</xsl:when>
<xsl:when test="count(*) > 0">
<!-- go recursive -->
<xsl:element name="{local-name()}">
<xsl:for-each select="current()/@*">
<xsl:attribute name="{local-name()}"><xsl:copy-of select="current()"/></xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="*" mode="codelist">
<xsl:with-param name="column" select="current()" />
</xsl:apply-templates>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- copy all element with value -->
<xsl:copy-of select="current()" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>

</xsl:template>
</xsl:stylesheet>

Thanks for your help in advance.

Best regards,

Marek

Postnext
Minollo I.Subject: recursive copy tree with special change
Author: Minollo I.
Date: 03 Jan 2006 10:17 AM
This is what I meant with "decouple the loop"; would this work for you?

<xsl:template match="*" mode="codelist">
<xsl:variable name="value" xmlns:saxon="http://saxon.sf.net/">
<xsl:copy-of select="saxon:parse(concat('&lt;root&gt;',.,'&lt;/root&gt;'))"/>
</xsl:variable>
<xsl:for-each select="$value/root//code">
<!-- get value from codelist -->
<xsl:variable name="codevalue" select="."/>
<xsl:apply-templates select="$codelist/*[code = $codevalue]" mode="list">
<xsl:with-param name="value" select="$codevalue"/>
</xsl:apply-templates>
</xsl:for-each>
<xsl:for-each select="$value/root/*[local-name() != 'code']">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>

Postnext
Marek KucharikSubject: recursive copy tree with special change
Author: Marek Kucharik
Date: 03 Jan 2006 10:25 AM
unfortunatelly it is not working because appropriate <list> for <code> will not be in the right place in output XML :(
but still thanks for your help and ideas

Postnext
Minollo I.Subject: recursive copy tree with special change
Author: Minollo I.
Date: 03 Jan 2006 10:59 AM
Not knowing the meaning of what I'm dealing with, I feel like shooting in the dark; but this will preseve the order of elements:

<xsl:template match="*" mode="codelist">
<xsl:variable name="value" xmlns:saxon="http://saxon.sf.net/">
<xsl:copy-of select="saxon:parse(concat('&lt;root&gt;',.,'&lt;/root&gt;'))"/>
</xsl:variable>
<xsl:for-each select="$value/root/*">
<xsl:choose>
<xsl:when test="local-name() = 'code'">
<!--get value from codelist -->
<xsl:variable name="codevalue" select="."/>
<xsl:apply-templates select="$codelist/*[code = $codevalue]" mode="list">
<xsl:with-param name="value" select="$codevalue"/>
</xsl:apply-templates>
</xsl:when>
<xsl:when test=".//*[local-name() = 'code']">
<!--get value from codelist -->
<xsl:variable name="codevalue" select=".//*[local-name() = 'code']"/>
<xsl:apply-templates select="$codelist/*[code = $codevalue]" mode="list">
<xsl:with-param name="value" select="$codevalue"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>

Posttop
Marek KucharikSubject: recursive copy tree with special change
Author: Marek Kucharik
Date: 04 Jan 2006 05:38 AM
it looks better but at the time it removes parent element when <code> is a child.
see example XML:
<column>
<code>anyvalue1</code>
<hs column="20" />
<bold><code>anyvalue2</code></bold>
<column>
result is:
<list><item>value1</item></list>
<hs column="20" />
<list><item>value2</item></list>

without parent <bold> element :(

 
Topic Page 1 2 3 4 5 6 7 8 9 Go to previous topicPrev TopicGo to next topicNext Topic
Download A Free Trial of Stylus Studio 6 XML Professional Edition Today! Powered by Stylus Studio, the world's leading XML IDE for XML, XSLT, XQuery, XML Schema, DTD, XPath, WSDL, XHTML, SQL/XML, and XML Mapping!  
go

Log In Options

Site Map | Privacy Policy | Terms of Use | Trademarks
Stylus Scoop XML Newsletter:
W3C Member
Stylus Studio® and DataDirect XQuery ™are from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2016 All Rights Reserved.