|
next
|
Subject: 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><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" ></column>
<type>Nisa72x60</type>
<number>1</number>
<clear>true </clear>
</row>
</BOARDS>
<PLANE_1>
<row>
<rowOrder>18</rowOrder>
<column><code>15196927</code><hs column="10" /><color val="yellow"><hs column="20" /></color><hs column="30" /><blink>Dec 29 2005 5:05PM</blink><hs column="40" /><bold><code>15196927_VASS</code></bold><br/></column>
</row>
</PLANE_1>
<CODELIST>
<row>
<code>15196927</code>
<column><item>OK0618</item></column>
</row>
<row>
<code>15196927_VASS</code>
<column><item>VASS</item><item>SKBA</item><item>EGYP</item></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('<',$main_element,'>')" />
<xsl:variable name="end_element" select="concat('</',$main_element,'>')" />
<!-- 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" ></boards></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('<root>',$column,'</root>'))"/>
</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
|
next
|
Subject: 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><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" ></column>
<type>Nisa72x60</type>
<number>1</number>
<clear>true </clear>
</row>
</BOARDS>
<PLANE_1>
<row>
<rowOrder>18</rowOrder>
<column><hs column="10" /><code>15196927</code><color val="yellow"><blink><hs column="30" /><blink>Dec 29 2005 5:05PM</blink></blink></color><hs column="30" /><blink>Dec 29 2005 5:05PM</blink><hs column="40" /><bold><code>15196927_VASS</code></bold><br/></column>
</row>
</PLANE_1>
<CODELIST>
<row>
<code>15196927</code>
<column><item>OK0618</item></column>
</row>
<row>
<code>15196927_VASS</code>
<column><item>VASS</item><item>SKBA</item><item>EGYP</item></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('<',$main_element,'>')" />
<xsl:variable name="end_element" select="concat('</',$main_element,'>')" />
<!-- 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" ></boards></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('<root>',$column,'</root>'))"/>
</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
|
|
|
|