Link to home
Start Free TrialLog in
Avatar of akusa8
akusa8

asked on

generate random or sequential numbers using xslt

Hi

How can you generate random numbers or sequential numbers in xslt?

Thanks  in advance for your help.
Avatar of kmartin7
kmartin7
Flag of United States of America image

<xsl:value-of select="generate-id()"/>

There are other ways, but not knowing exactly what you are looking for, the above is a fairly simple method that might give you what you need.

kmartin7
Avatar of Gertone (Geert Bormans)
for random you can use
http://www.exslt.org/random/index.html
if your processor supports exslt

usually sequential numbering is easier if you have something to count.
For that I need to know what exactly you are trying to do, with what data
Avatar of akusa8
akusa8

ASKER

Hi

Thanks for your solutions. What I have is a bunch of XML files for which I am generating a file name. The root element is <product> for all the files. My file name convention is 1234-5{seq-num}. After 5, I need to generate a 3 digit sequence number for each of the XML files in the directory.

I am using Saxon 9.

Is it possible to generate sequential numbers for this case?
can you show me the code?
If you use saxon 9, there is a randomize function in XSLT2
but if you are scanning the directory, you can use position() most likely,
so please show me the code
Avatar of akusa8

ASKER

Well, I have written a function. But the problem is when I use <xsl:number> all files will have 1234-5001.

I also forgot to mention that after '5' I can only have 3 digits.

<xsl:variable name="seq">
            <xsl:number  format="001" level="single"/>
      </xsl:variable>

      <xsl:function name="ak:calc-num">
            <xsl:param name="num"/>
            <xsl:value-of select="concat('1234-5', $seq)"/>
      </xsl:function>

that is because you didn't change the context likely.
small bug in your code that is,
can you post the entire stylesheet? or at least the template in which this happens?
Avatar of akusa8

ASKER

Sure.  I will explain this a little more here. Below is the template  I am using it to push out filenames.

<xsl:template match="/">
            <xsl:param name="num" select="ak:calc-num($file)"/>
            <xsl:for-each select=".">
                              <xsl:result-document method="xml" href="{$num}.xml" indent="yes">
                                    <xsl:apply-templates/>
                              </xsl:result-document>
                        </xsl:for-each>

</xsl:template>

The $file is embedded in the source xml.
So my source XML is:

<product>
<metadata name="cat' con="2222"/>
 </product>

So $file = '2222' This number varies from file to file and based on whether the first digit is 1, 2 or 3, I have different conditions for the output file name. Atleast that is the desire. I am trying it out for the first file name. When it starts with '2', I want the output to be 1234-5 and a 3 digit sequential number after that.

If the source XML element 'cat' starts with 3, then I would want it as 5678-9 and a 3 digit sequence. I know how to get that mapping done. But I wasn't sure on how to get the last three digits to be unique and sequential.


Avatar of akusa8

ASKER

Hi

Can someone please help me here?
I can't figure out your stylesheet actually.
I thought of using a position() for the numbering, which makes more sense, but I am not sure.
This stylesheet actually only makes one output document, so I am afraid that I don't grasp the whole of it.

Do you read all the different input files using saxon, or do you call a process for every file.
If the later is the case, I am afraid that you will need to pass a sequential number as a parameter to the stylesheet
Random will not help you since it will not garantuee uniqueness.
So having a counter outside the XSLT is your best option.
How do you call the XSLT, dos batch? shell script? Java?
Avatar of akusa8

ASKER

I run the transformation in a batch mode using saxon's command line.
one file each?
Well, there are two things you can consider
- move part of the batch logic into saxon by repeating over a list of files found using doc(), then you have the position() at hand to increase the numbering
- add a logic for numbering the iteration over the file in the batch logic, so you can pass the number as a parameter to teh XSLT

I have done the first a number of times allready, works really well.
I have done the second approach a couple of times from Python and javascript/java, works well. It should be possible to add that to your logic in batch as well

I have to go now, but tomorrow I might give you some code for the first option
I prefer the first option by the way, allthough you need a slight redesign for your stylesheet
Avatar of akusa8

ASKER

Hi

Thanks for your response.

Can you please give me some sample code for javascript/java as well?
Avatar of akusa8

ASKER

Hi

Can someone help me here pleasE?
Avatar of akusa8

ASKER

I take it that nobody will be able to answer my question. Thanks for all your help.
Hi, I missed  a bunch of follow-up messages it seems, sorry about that
seems I did not get a mail for those.
Let me see what I can do here, not today, likely tomorrow morning
ASKER CERTIFIED SOLUTION
Avatar of Gertone (Geert Bormans)
Gertone (Geert Bormans)
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
If you want to pass in the unique number (just increment a counter for each XSLT process you start on a file)
look at the APi of what you are actually starting the XSLT process from