Page 1 of 1

Change multiple elements of type X for a single type Y

Posted: Wed Aug 22, 2012 7:05 pm
by William
Hello.

I have in my XML 10000s of elements formatted thus:

Code: Select all


<row id="1" value="488" />
<row ... />
<row id="499" value="488" />
<row id="500" value="221" />
<row ... />
<row id="1924" value="221" />
<row id="1925" value="3213" />
<.../>
However the Schema supports an alternative format:

Code: Select all


<sparse start="1" end="499" value="488"/>
<sparse start="500" end="1924" value="221"/>
<sparse start="1925" end="11044" value="3213"/>
Using the <sparse> element type eliminates a lot of 'redundant' XML and results in a reduced parse time.

So I would like to create a template | function that allows me to swap out the <row> elements in favour of the <sparse>, but in order to do this I need to obtain the following information.

A sequence containing the position() or the @id of each change in value, so I can use it (-1) for the @end and as it is for the @starts. I can of course get a sequence of @value using distinct-values().

Which brings up another question why when I do this:

Code: Select all


<xsl:variable name="values" select="distinct-values(./row/@value)" as="xs:integer*"/>
<xsl:message select="'Value ', $values[1]"/>
<xsl:message select="'Value ', $values[2]"/>
Do I get what I deem to be the correct output:

Code: Select all


Value 488
Value 221
But doing this:

Code: Select all


<xsl:for-each select="1 to count($values)">
<xsl:element name="sparse">
<xsl:attribute name="pos" select="position()"/>
<xsl:attribute name="value" select="$values[position()]"/>
</xsl:element>
</xsl:for-each>
Results in this !:

Code: Select all


<sparse pos="1" value="488 221"/>
<sparse pos="2" value="488 221"/>
Or is this another topic?

--
William