473,698 Members | 2,343 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

XSLT - maintaining iteration count

I have an XSLT script that has to operate on some particularly nasty XML to
turn it into a SQL databse, but 'entries' in the XML aren't actually
unique, so their unique identifier is useless. I need to somehow create
crosslinked tables using the XSLT, but can only do this by maintaining a
counter for each line I write.

Is there a way to create a proxy 'increment' function that lets me maintain
a counter variable?

- Mike Kamermans
Jul 20 '05 #1
6 10617
To be more specific, I have an XML document consisting of entries roughly
like this:

<entry>
<seq_num>8173 2</seq_num>
<k_entries>
<k val="kval1"/>
<k val="kval2"/>
</k_entries>
<r_entries>
<r val="rval1"/>
<r val="rval2"/>
</r_entries>
</entry>

The XSLT operates using a for-each for entries, and needs to do all
combinations of [k] and [r] values. In non-XSL format I'd like to do the
following:

counter = 1;
foreach (entry in document)
foreach (k in entry)
foreach (r in entry)
(create a SQL like with the values of [counter/k/r])
(increment the counter by one)
/foreach
/foreach
/foreach

I'm not sure how to make this work in XSLT.

- Mike
Jul 20 '05 #2


something like

<xsl:for-each select="entry">
<xsl:for-each select="k_entri es/k">
<xsl:value-of name="k" select="."/>
<xsl:for-each select="../../r_entries/r">
<xsl:variable name="n">
<xsl:number level="any" count="k|r"/>
</xsl:variable>
do something with . $k and $n
..

David
Jul 20 '05 #3
David,
<xsl:for-each select="entry">
<xsl:for-each select="k_entri es/k">
<xsl:value-of name="k" select="."/>
<xsl:for-each select="../../r_entries/r">
<xsl:variable name="n">
<xsl:number level="any" count="k|r"/>
</xsl:variable>
do something with . $k and $n
..


Sadly, that'd only maintain the count inside an entry. this would still
leave the matter of maintaining the count for the whole document. for
instance, a document like

<doc>
<entry>
<k_entries><k val="ka"/><k val="kb"/></k_entries>
<r_entries><r val=ra"/></r_entries>
</entry>
<entry>
<k_entries><k val="kc"/></k_entries>
<r_entries><r val=rb"/><r val=rc"/><r val=rd"/></r_entries>
</entry>
<entry>
<k_entries><k val="kd"/></k_entries>
<r_entries><n val=re"/></r_entries>
</entry>
</doc>

Would have to end up looking like the following text:

insert into entry_table (id,k,r) values (1, ka, ra);
insert into entry_table (id,k,r) values (2, kb, ra);
insert into entry_table (id,k,r) values (3, kc, rb);
insert into entry_table (id,k,r) values (4, kc, rc);
insert into entry_table (id,k,r) values (5, kc, rd);
insert into entry_table (id,k,r) values (6, kd, re);

Know of any way to maintain a counter that creates these 'id' values
correctly?

- Mike
Jul 20 '05 #4
Sadly, that'd only maintain the count inside an entry.
No, if you wanted that you'd have to add from="entry" the default is the
whole document.
Know of any way to maintain a counter that creates these 'id' values
correctly?


As I posted.

David
Jul 20 '05 #5

I wrote
Sadly, that'd only maintain the count inside an entry.
No, if you wanted that you'd have to add from="entry" the default is the
whole document.


This is true.

Know of any way to maintain a counter that creates these 'id' values
correctly?


As I posted.

That is true as written, but not entirely helpful as xsl:number counts
the input tree (in this case the sum of the number of k and r nodes)
but you want the count in the output (essentially the product in this
case)

Your original post indicated that actually you just need a unique
identifier rather than a count, that's easier in xslt, the default mode
in the code below produces
[81732,kval1,rva l1][d0e3d0e10d0e17]
[81732,kval1,rva l2][d0e3d0e10d0e19]
[81732,kval2,rva l1][d0e3d0e12d0e17]
[81732,kval2,rva l2][d0e3d0e12d0e19]
[81732,kval1,rva l1][d0e23d0e30d0e37]
[81732,kval1,rva l2][d0e23d0e30d0e39]
[81732,kval2,rva l1][d0e23d0e32d0e37]
[81732,kval2,rva l2][d0e23d0e32d0e39]

on

<entries>
<entry>
<seq_num>8173 2</seq_num>
<k_entries>
<k val="kval1"/>
<k val="kval2"/>
</k_entries>
<r_entries>
<r val="rval1"/>
<r val="rval2"/>
</r_entries>
</entry>
<entry>
<seq_num>8173 2</seq_num>
<k_entries>
<k val="kval1"/>
<k val="kval2"/>
</k_entries>
<r_entries>
<r val="rval1"/>
<r val="rval2"/>
</r_entries>
</entry>
</entries>
which has a duplicated entry element.
You'll see the first [] on each line iterates twice through the k and r
values, but the second [] on each line is unique.

If you do need a count you have to work (a bit) harder. as shown in mode
b which passes the "count so far" as a parameter to the template for
entry. so in this case you get

[81732,kval1,rva l1][1]
[81732,kval1,rva l2][2]
[81732,kval2,rva l1][3]
[81732,kval2,rva l2][4]
[81732,kval1,rva l1][5]
[81732,kval1,rva l2][6]
[81732,kval2,rva l1][7]
[81732,kval2,rva l2][8]
David
<xsl:styleshe et
version="1.0"
xmlns:xsl="http ://www.w3.org/1999/XSL/Transform"


<xsl:template match="entries" >
<xsl:apply-templates select="entry"/>
<xsl:apply-templates mode="b" select="entry[1]"/>
</xsl:template>

<xsl:template match="entry">
<xsl:variable name="e" select="."/>
<xsl:for-each select="k_entri es/k">
<xsl:variable name="k" select="."/>
<xsl:for-each select="../../r_entries/r">
[<xsl:value-of select="concat( $e/seq_num,',',$k/@val,',',@val,'][',generate-id($e),generate-id($k),generate-id(.),']')"/>
</xsl:for-each>
</xsl:for-each>
</xsl:template>

<xsl:template match="entry" mode="b">
<xsl:param name="c" select="0"/>
<xsl:variable name="e" select="."/>
<xsl:variable name="nr" select="count(r _entries/r)"/>
<xsl:for-each select="k_entri es/k">
<xsl:variable name="k" select="."/>
<xsl:variable name="kp" select="positio n()"/>
<xsl:for-each select="../../r_entries/r">
[<xsl:value-of select="concat( $e/seq_num,',',$k/@val,',',@val,'][',$c+($kp -1)*$nr + position(),']')"/>
</xsl:for-each>
</xsl:for-each>
<xsl:apply-templates select="followi ng-sibling::entry[1]" mode="b">
<xsl:with-param name="c" select="$c + $nr * count(k_entries/k)"/>
</xsl:apply-templates>
</xsl:template>

</xsl:stylesheet>
Jul 20 '05 #6

"M.Kamerman s" <mk******@scien ce.uva.nl> wrote in message
news:Xn******** *************** **********@213. 75.12.135...
To be more specific, I have an XML document consisting of entries roughly
like this:

<entry>
<seq_num>8173 2</seq_num>
<k_entries>
<k val="kval1"/>
<k val="kval2"/>
</k_entries>
<r_entries>
<r val="rval1"/>
<r val="rval2"/>
</r_entries>
</entry>

The XSLT operates using a for-each for entries, and needs to do all
combinations of [k] and [r] values. In non-XSL format I'd like to do the
following:

counter = 1;
foreach (entry in document)
foreach (k in entry)
foreach (r in entry)
(create a SQL like with the values of [counter/k/r])
(increment the counter by one)
/foreach
/foreach
/foreach

I'm not sure how to make this work in XSLT.

- Mike

Here's a quick XSLT 2.0 + FXSL solution:

This transformation:

<xsl:styleshe et version="2.0"
xmlns:xsl="http ://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="f xs" <xsl:import href="../f/func-standardXpathFu nctions.xsl"/>
<xsl:import href="../f/func-map.xsl"/>

<xsl:output omit-xml-declaration="ye s" indent="yes"/>

<xsl:template match="/">
<xsl:for-each select=
"for $indEntry in 1 to count(/*/entry),
$ind-r_entry in 1 to count(/*/entry[$indEntry]/r_entries/r)
return
f:map(f:insert-before(data(/*/entry[$indEntry]/r_entries/r[$ind-r_entry]/@val),1),
data(/*/entry[$indEntry]/k_entries/*/@val)
) "


<xsl:value-of select="if(posi tion() mod 2 = 1) then
(position() + 1) idiv 2,
', ', ., ', '
else
(. , '&#xA;')
"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

when applied on this source xml document:

<cat>
<entry>
<seq_num>8173 2</seq_num>
<k_entries>
<k val="kval1"/>
<k val="kval2"/>
</k_entries>
<r_entries>
<r val="rval1"/>
<r val="rval2"/>
</r_entries>
</entry>
<entry>
<seq_num>8174 2</seq_num>
<k_entries>
<k val="kval3"/>
<k val="kval4"/>
</k_entries>
<r_entries>
<r val="rval3"/>
<r val="rval4"/>
</r_entries>
</entry>
<entry>
<seq_num>8175 2</seq_num>
<k_entries>
<k val="kval5"/>
<k val="kval6"/>
</k_entries>
<r_entries>
<r val="rval5"/>
<r val="rval6"/>
</r_entries>
</entry>
</cat>

produces the desired result:

1 , kval1 , rval1
2 , kval2 , rval1
3 , kval1 , rval2
4 , kval2 , rval2
5 , kval3 , rval3
6 , kval4 , rval3
7 , kval3 , rval4
8 , kval4 , rval4
9 , kval5 , rval5
10 , kval6 , rval5
11 , kval5 , rval6
12 , kval6 , rval6

Cheers,

Dimitre Novatchev
Jul 20 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
9551
by: inquirydog | last post by:
Hi- Does anyone know a way to compare whether two nodes contain the same information in xslt (the name, attributes, and all content recursivly should be the same. I am interested in the case where node ordering matters, and also the case where it doesn't, but perhaps that is an advanced topic). Ideally the method should be available to xpath expressions, so I think that creating new templates which compare nodes will not work (well,...
1
425
by: karthigan | last post by:
I am writing a simple hardware test program in C that would run from Windows command line. Inside one of the loops, I have this code fragment that would display the Iteration count. { .... system("cls"); printf("\nIteration:%d", i);
1
2367
by: cameron | last post by:
I am attempting to pass in an XmlDocument as a parameter to a transform: from my sample ASPX page: string BaseDir = "/cameron/Play/ComplexParam/"; XmlDocument XSL = new XmlDocument(); XSL.Load(HttpContext.Current.Server.MapPath(BaseDir + "xsl.xsl")); XmlDocument Data = new XmlDocument();
6
2502
by: Michiel Kamermans | last post by:
Hi, I need to generate a list based on a sorted nodeset, except duplicates need to be discarded. I initially though of doing a sort on a nodeset and then passing it to a template that iterates over the set and compares the current element it's processing to the previous one, continueing to the next element immediately if it was the same as the previous one. However, quite annoyingly the xsl:sort command cannot "just" be called, I need...
4
5741
by: gualtmacchi | last post by:
I'm processing an XML input file getting a plain text file where from M nodes I got N output lines... It's not relevant but the input file is a recordset coming from a database and the output is an EDI message set. Now I need to put into the output file also some information regarding just the output file itself and not the input one. And it cannot be expressed in terms of input information. For example I need to determine and write how...
1
1640
by: jrwarwick | last post by:
Hello, I believe I have uncovered a bug in the .Net XSLT engine to do with 'for' loops in XSLT. Here are the steps to reproduce it: -Create A new webform project. -Add the xml file 'errorexample.xml' - it is shown at the bottom -Add the xslt file 'errorexample.xslt' - it is shown at the bottom -Add a label into the WebForm1.aspx designer and stretch it so it is large, give it the ID of Output1. -Import the following namespaces in...
2
1692
by: Adam dR. | last post by:
I have an xml file similar to: <menu> <menuitem name="home" show="false"/> <menuitem name="about" show="true"/> <menuitem name="links" show="true"/> <menuitem name="games" show="true"/> <menuitem name="learn" show="true"/> <menuitem name="order" show="true"/> <menuitem name="contact" show="true"/> <menuitem name="support" show="false"/>
4
1925
by: shaun roe | last post by:
I should like to count the frequency of strings embedded in a longer string, space separated. Specifically, I have: <phiModule> 5 5 5 5 6 6 6 6 7 7 7 7 8 8 8 8 8 5 5 5 6 6 6 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 9 9 9 9 6 7 7 7 8 8 8 8 9 9 9
0
1754
by: Leira | last post by:
Hi, I have a problem with grouping. My source XML has <record> elements that have a @name and a @group attribute. It looks something like this: <root> <result> <record name="test1" group="group1"><value>1A</value></record> <record name="test2" group="group1"><value>1B</value></record> <record name="test3" group="group1"><value>1C</value></record> <record name="test1" group="group2"><value>2A</value></record>
0
8674
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8604
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9157
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9028
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8895
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8861
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6518
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5860
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
3046
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.