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
Conferences Close Tree View
+ Stylus Studio Feature Requests (1192)
+ Stylus Studio Technical Forum (14621)
+ Website Feedback (249)
- XSLT Help and Discussion (7625)
-> + Use of before and after string (3) Sticky Topic
-> - How do I substitute element ty... (1)
-> + How does one add working days ... (4)
-> - Help, I have existing XLT and... (1)
-> + Need help on XSLT issue - (2)
-> + EDI to XML Conversion (7)
-> - XML To JSON Conversion using X... (1)
-> + Formatting Paragraphs to same ... (2)
-> - Grouping of records (1)
-> + Problems with xsd 1.1 (4)
-> + XML to HL7 mapping (3)
-> + XSLT 3 and Iterate (2)
-> + XSL-FO to PDF preview (3)
-> + java.lang.RuntimeException: Er... (2)
-> + Create Acroforms with Stylus X... (2)
-> + How to change XSLT parameter s... (3)
-> + how to change format of the da... (2)
-> + Search "Next 8 Results " doesn... (2)
-> - Support for Git (1)
-> + newbee (8)
-- [1-20] [21-40] [41-60] Next
+ XQuery Help and Discussion (2017)
+ Stylus Studio FAQs (159)
+ Stylus Studio Code Samples & Utilities (364)
+ Stylus Studio Announcements (113)
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 :(

   
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.