Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > XML > XSLT Transform Vector to Array

Reply
Thread Tools

XSLT Transform Vector to Array

 
 
Gary Huntress
Guest
Posts: n/a
 
      08-13-2004
Hi,

I'm having trouble with an xslt transform. I'm trying to transform a
vector into an array of width N. For example here is my vector:

<data>
<x id="1">1.2</x>
<x id="2">.2</x>
<x id="3">.87</x>
<x id="4">.333</x>
<x id="5">.4442</x>
<x id="6">1.1</x>
<x id="7">.8</x>
<x id="8">.6543</x>
<x id="9">.8761</x>
<x id="10">1</x>
<x id="11">.99</x>
<x id="12">.2</x>
</data>

and given N=4 I want to transform it to

<array>
<row id="1">
<x id="1">1.2</x>
<x id="2">.2</x>
<x id="3">.87</x>
<x id="4">.333</x>
</row>
<row id="2">
<x id="1">.4442</x>
<x id="2">1.1</x>
<x id="3">.8</x>
<x id="4">.6543</x>
</row>
<row id="3">
<x id="1">.8761</x>
<x id="2">1</x>
<x id="3">.99</x>
<x id="4">.2</x>
</row>
</array>

I can successfully use @id mod $N to identify each <row> but I have
not found a way to properly create the output. Here is a failed
attempt:

<xsl:template match="x">
<xsl:choose>
<xsl:when test="(@id mod 4)=1">
<row>
<x><xsl:value-of select="."/></x>
</row>
</xsl:when>
<xsltherwise>
<x><xsl:value-of select="."/></x>
</xsltherwise>
</xsl:choose>
</xsl:template>

The "otherwise" <x> elements are not properly nested in the <row> and
I don't know how to make them children of the newly created <row>.

Should I be using an axis here? Or am I missing an obvious solution?

Thx,

Gary H.
 
Reply With Quote
 
 
 
 
=?ISO-8859-1?Q?R=E9mi_Peyronnet?=
Guest
Posts: n/a
 
      08-13-2004
> The "otherwise" <x> elements are not properly nested in the <row> and
> I don't know how to make them children of the newly created <row>.


I see two solutions :

1/ The quick'n dirty one : use text output, and CDATA section

Thus you will be able to <![CDATA[</row><row>]]> :

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlnssl="http://www.w3.org/1999/XSL/Transform">
<xslutput method = "text" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:template match="/">
<![CDATA[<row>]]>
<xsl:apply-templates />
<![CDATA[</row>]]>
</xsl:template>

<xsl:template match="x">
<xsl:choose>
<xsl:when test="(@id mod 4)=0">
<!--<row> -->
<![CDATA[<x>]]><xsl:value-of select="."/><![CDATA[</x>]]>
<![CDATA[</row>
<row>]]>
</xsl:when>
<xsltherwise>
<![CDATA[<x>]]><xsl:value-of select="."/><![CDATA[</x>]]>
</xsltherwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>

Improvements should be done to remove the trailing <row></row> if it is
unacceptable.


2/ Another way, based on modes

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlnssl="http://www.w3.org/1999/XSL/Transform">

<xsl:variable name="N">4</xsl:variable>

<xsl:template match="/">
<array>
<xsl:apply-templates />
</array>
</xsl:template>

<xsl:template match="x">
<xsl:if test="(@id mod $N) = 1">
<row>
<!-- Use this for ordered contents, quicker
<xsl:apply-templates select="current()" mode="display" />
<xsl:apply-templates select="following-sibling::*[position() &lt;
$N]" mode="display" />
-->
<!-- Use this for non-ordered contents -->
<xsl:apply-templates select="../x[(@id &gt;=current()/@id) and (@id
&lt; current()/@id + $N)]" mode="display" />
</row>
</xsl:if>
</xsl:template>

<xsl:template match="x" mode="display">
<x><xsl:apply-templates /></x>
</xsl:template>

</xsl:stylesheet>

Hth

--
Rémi Peyronnet
 
Reply With Quote
 
 
 
 
Marrow
Guest
Posts: n/a
 
      08-14-2004
Hi Gary,

Try something like...

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlnssl="http://www.w3.org/1999/XSL/Transform">
<xslutput method="xml" indent="yes"/>
<xslaram name="array_width" select="4"/>

<xsl:template match="data">
<array>
<xsl:apply-templates select="x[(position() mod $array_width = 1) or
($array_width = 1)]" mode="row-start"/>
</array>
</xsl:template>

<xsl:template match="x" mode="row-start">
<row id="{position()}">
<xsl:copy-of select=". | following-sibling:[position() &lt;
$array_width]"/>
</row>
</xsl:template>

</xsl:stylesheet>


HTH
Marrow
http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger)
http://www.topxml.com/Xselerator

"Gary Huntress" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> Hi,
>
> I'm having trouble with an xslt transform. I'm trying to transform a
> vector into an array of width N. For example here is my vector:
>
> <data>
> <x id="1">1.2</x>
> <x id="2">.2</x>
> <x id="3">.87</x>
> <x id="4">.333</x>
> <x id="5">.4442</x>
> <x id="6">1.1</x>
> <x id="7">.8</x>
> <x id="8">.6543</x>
> <x id="9">.8761</x>
> <x id="10">1</x>
> <x id="11">.99</x>
> <x id="12">.2</x>
> </data>
>
> and given N=4 I want to transform it to
>
> <array>
> <row id="1">
> <x id="1">1.2</x>
> <x id="2">.2</x>
> <x id="3">.87</x>
> <x id="4">.333</x>
> </row>
> <row id="2">
> <x id="1">.4442</x>
> <x id="2">1.1</x>
> <x id="3">.8</x>
> <x id="4">.6543</x>
> </row>
> <row id="3">
> <x id="1">.8761</x>
> <x id="2">1</x>
> <x id="3">.99</x>
> <x id="4">.2</x>
> </row>
> </array>
>
> I can successfully use @id mod $N to identify each <row> but I have
> not found a way to properly create the output. Here is a failed
> attempt:
>
> <xsl:template match="x">
> <xsl:choose>
> <xsl:when test="(@id mod 4)=1">
> <row>
> <x><xsl:value-of select="."/></x>
> </row>
> </xsl:when>
> <xsltherwise>
> <x><xsl:value-of select="."/></x>
> </xsltherwise>
> </xsl:choose>
> </xsl:template>
>
> The "otherwise" <x> elements are not properly nested in the <row> and
> I don't know how to make them children of the newly created <row>.
>
> Should I be using an axis here? Or am I missing an obvious solution?
>
> Thx,
>
> Gary H.



 
Reply With Quote
 
David Carlisle
Guest
Posts: n/a
 
      08-16-2004

<xsl:variable name="N" select="4"/>

<xsl:template match="data">
<array>
<xsl:for-each select="x[position() mod $N = 1]">
<row>
<xsl:for-each select=".|following-sibling:[position() &lt; $N]">
<x id="position()"><xsl:value-of select="."/></x>
</xsl:for-each>
</row>
</xsl:for-each>
</array>
</xsl:template>
 
Reply With Quote
 
Robin Johnson
Guest
Posts: n/a
 
      08-16-2004
Rémi Peyronnet <(E-Mail Removed)> wrote in message news:<cfiuo4$ue$(E-Mail Removed)>...
> > The "otherwise" <x> elements are not properly nested in the <row> and
> > I don't know how to make them children of the newly created <row>.

>
> I see two solutions :
>
> 1/ The quick'n dirty one : use text output, and CDATA section
>
> Thus you will be able to <![CDATA[</row><row>]]> :


Sorry to slur your coding style, sir, but AAARGH! KILL IT!

Use the mod operator to select every n'th <x> element, then sweep over
"self:|following-sibling:[position() &lt; $n]" to produce each
row.
--
Robin Johnson
Lead Developer, enCircle Solutions Ltd.
first initial last name at encircle dot co dot uk
 
Reply With Quote
 
=?ISO-8859-1?Q?R=E9mi_Peyronnet?=
Guest
Posts: n/a
 
      08-17-2004
Robin Johnson a écrit :

>>1/ The quick'n dirty one : use text output, and CDATA section

>
> Sorry to slur your coding style, sir, but AAARGH! KILL IT!


Of course, you're right ; that is why there was a second and recommended
solution in my post

> Use the mod operator to select every n'th <x> element, then sweep over
> "self:|following-sibling:[position() &lt; $n]" to produce each
> row.


Does only work if elements are sorted, as stated in my second solution :
"
<!-- Use this for ordered contents, quicker
<xsl:apply-templates select="current()" mode="display" />
<xsl:apply-templates select="following-sibling::*[position() &lt;
$N]" mode="display" />
-->
<!-- Use this for non-ordered contents -->
<xsl:apply-templates select="../x[(@id &gt;=current()/@id) and (@id
&lt; current()/@id + $N)]" mode="display" />
"

But I still think the first solution has to be thought for very special
cases much more complicated with the second version, and for codes only
used once. Wasn't the case here, I agree.

--
Rémi Peyronnet
 
Reply With Quote
 
Robin Johnson
Guest
Posts: n/a
 
      08-17-2004
On Tue, 17 Aug 2004 20:37:33 +0200, Rémi Peyronnet
<(E-Mail Removed)> wrote:
> Robin Johnson a écrit :
>> Use the mod operator to select every n'th <x> element, then sweep over
>> "self:|following-sibling:[position() &lt; $n]" to produce each
>> row.

>
>Does only work if elements are sorted, as stated in my second solution :


Noted.

>But I still think the first solution has to be thought for very special
>cases much more complicated with the second version, and for codes only
>used once.


Yes, I've done the same myself in a few cases (notably when
suppressing output escaping in attribute values*), but I'm not proud.

* There's a saxon extension for that now, of course.
--
Robin Johnson
Lead Developer, enCircle Solutions Ltd.
first initial last name at encircle dot co dot uk
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Initializing vector<vector<int> > and other vector questions... pmatos C++ 6 04-26-2007 05:39 PM
Free memory allocate by a STL vector, vector of vector, map of vector Allerdyce.John@gmail.com C++ 8 02-18-2006 12:48 AM
Uniform vector class, inheriting from Array: How to make sure thatmethods return a Vector and not an Array? Thomas Ruby 7 05-23-2005 04:21 PM
blocking I/O with javax.xml.parsers.DocumentBuilder.parse() and javax.xml.transform.Transformer.transform() jazzdman@gmail.com Java 1 03-27-2005 06:56 AM



Advertisments