4

How can I generate a unique and random string with xslt in order to associate it to an attribute of a tag. for eg I want to add a unique id to this tag

<generalization xmi:id="unique ID">
Iheb
  • 61
  • 1
  • 6
  • possible duplicate of [XSLT generate UUID](http://stackoverflow.com/questions/8126963/xslt-generate-uuid) – Glorfindel May 12 '15 at 15:55
  • 4
    Isn't the `generate-id()` XSL function sufficient for what you want to do? Can you explain further the use case of this new id? – potame May 12 '15 at 15:59
  • @potame I'm going to generate many tags named `generalization` but they must have random and unique IDs in order to not confond them – Iheb May 12 '15 at 16:35
  • I understand, but is it a so strong requirement to have it **random**?? `generate-id()` will of course ensure the id to be unique, on the other hand. – potame May 12 '15 at 19:30
  • So how can I generate IDs that can be unique using generate-id()? – Iheb May 12 '15 at 20:39

2 Answers2

2

You can use generate-id() to create unique identifiers. To quote the standard, "This function returns a string that uniquely identifies a given node."

Consider this stylesheet:

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

<!-- Replace <xyzzy> with <generalization xml:id="unique ID"> -->
<xsl:template match="xyzzy">
  <generalization>
    <xsl:apply-templates select="@*"/>
    <xsl:attribute name="xml:id"><xsl:value-of select="generate-id()"/></xsl:attribute>
    <xsl:apply-templates/>
  </generalization>
</xsl:template>

<!-- Copy everything else straight thru -->
<xsl:template match="node( ) | @*">
    <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>

</xsl:stylesheet>

applied to this input:

<?xml version='1.0' encoding='ASCII'?>
<root>
 <xyzzy/>
 <xyzzy a="b">
  <xyzzy xml:id="non-unique-id"/>
 </xyzzy>
</root>

With this result:

<?xml version="1.0"?>
<root>
 <generalization xml:id="idp28972496"/>
 <generalization a="b" xml:id="idp28945920">
  <generalization xml:id="idp28946416"/>
 </generalization>
</root>

Notice how the value of generate-id() is unique across the document.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
1

You can use generate-id() with a temporary XML node to create random strings of any length:

<!-- language: lang-xml -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:kh="https://github.com/kohsah"
    exclude-result-prefixes="xs xd"
    version="2.0">
    <xsl:function name="kh:shortRandom">
        <xsl:variable name="mxml">
            <node/>
        </xsl:variable>
        <xsl:sequence select="generate-id($mxml//node)"/>
    </xsl:function>

    <xsl:function name="kh:longRandom">
        <xsl:sequence select="concat(kh:shortRandom(), kh:shortRandom(), kh:shortRandom(), kh:shortRandom())"></xsl:sequence>
    </xsl:function>

    <xsl:template match="/">
        <test>
            <randomId><xsl:value-of select="kh:shortRandom()"/></randomId>
            <guid><xsl:value-of select="kh:longRandom()"/></guid>
        </test>
    </xsl:template>

</xsl:stylesheet>

There are two XSL functions here:

  • kh:shortRandom() which generates short 4 letter random strings like this one: "d2e1"
  • kh:longRandom() which generates longer 16 letter random strings like this one: "d3e1d4e1d5e1d6e1"
kohsah
  • 41
  • 1