c++xmlxsltxslt-1.0

Generating UUID in XSLT 1.0


In our legacy project we are using libxslt which is based on xslt 1.0 version. Now there is a need to generate UUID using the xslt file so that our output xml file contains the UUID.

As per https://stackoverflow.com/a/8127174/3747770 I am out of luck.

Also as per this https://gist.github.com/azinneera/778f69ae6b0049b5edcd69da70072405 we can generate UUID, but using xslt 2.0.

I am new to xslt, and is there any way to convert the https://gist.github.com/azinneera/778f69ae6b0049b5edcd69da70072405 style sheet from version 2.0 to 1.0 or is there any other way to generate UUID using xslt 1.0?


Solution

  • As I have stated in the comment to your question, if you are using the libxslt processor, you can use the EXSLT math:random() extension function to generate a sequence of random numbers that will eventually form a version 4 UUID.

    Here's an implementation example:

    XSLT 1.0 + EXSLT

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:math="http://exslt.org/math"
    xmlns:func="http://exslt.org/functions"
    xmlns:my="www.example.com/my"
    extension-element-prefixes="func math my">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <func:function name="my:UUID4">
        <!-- https://www.ietf.org/rfc/rfc4122.txt -->
        <func:result>
            <!-- 8 -->
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:text>-</xsl:text>      
            <!-- 4 -->
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <!-- version identifier -->
            <xsl:text>-4</xsl:text>     
            <!-- 3 -->
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:text>-</xsl:text>      
            <!-- 1* -->
            <xsl:value-of select="substring('89ab', floor(4*math:random()) + 1, 1)" />
            <!-- 3 -->
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:text>-</xsl:text>      
            <!-- 12 -->
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" />
            <xsl:value-of select="substring('0123456789abcdef', floor(16*math:random()) + 1, 1)" /> 
        </func:result>
    </func:function>
    
    <xsl:template match="/items">
        <output>
            <xsl:for-each select="item">
                <item id="{my:UUID4()}">
                    <xsl:value-of select="." />
                </item>
            </xsl:for-each>
        </output>
    </xsl:template>
    
    </xsl:stylesheet>
    

    When applied to the following input:

    XML

    <items>
        <item>1</item>
        <item>2</item>
        <item>3</item>
        <item>4</item>
        <item>6</item>
        <item>7</item>
        <item>8</item>
        <item>9</item>
    </items>
    

    I got the following result:

    Result 1

    <?xml version="1.0" encoding="UTF-8"?>
    <output>
      <item id="77587d4c-1ef6-4aaf-9f97-398dee70fa25">1</item>
      <item id="148e4218-c881-41d3-af61-cab4b5d0251f">2</item>
      <item id="3a02b568-3200-46ff-993c-3bea9724d6ce">3</item>
      <item id="28de29bd-39f4-4eed-979a-765c290652a1">4</item>
      <item id="7c767fa7-c0b7-4187-9f86-d3876ec1be8a">6</item>
      <item id="aca2261f-e837-4a2d-a555-0c81b2c7f7a2">7</item>
      <item id="b7ecb7bd-8c3e-475d-ba17-4c62c1c3d90b">8</item>
      <item id="d28f95e8-452c-474f-9c9a-11e09cd948ae">9</item>
    </output>
    

    Subsequent runs produced:

    Result 2

    <?xml version="1.0" encoding="UTF-8"?>
    <output>
      <item id="6eb63a8e-599d-450a-8970-a758b73aa121">1</item>
      <item id="86b247bf-81c8-47ce-9375-4a35e44fcde7">2</item>
      <item id="cbc04786-9e90-4331-a9d3-47955c7d5a99">3</item>
      <item id="9f82f8d0-9934-499e-8783-61087ebce2f7">4</item>
      <item id="5b77da5b-f28f-45a7-82f4-a47b6b1aa7b2">6</item>
      <item id="7eab11bc-209f-4100-b4e6-1cc0f73beda0">7</item>
      <item id="7f4151f4-6166-4406-9ee4-e7de325537d0">8</item>
      <item id="2185c4b8-6a74-4b97-93b4-872b2c0e1f5e">9</item>
    </output>
    

    Result 3

    <?xml version="1.0" encoding="UTF-8"?>
    <output>
      <item id="784b9cd0-a77a-4719-ad0b-183a970b6785">1</item>
      <item id="4dbed80b-4c82-4dde-8a0a-8b29471bdbbf">2</item>
      <item id="0297ad52-3070-4b6a-a28b-a9c7c4607027">3</item>
      <item id="8e402219-3fbf-4025-827b-c95ae4e12ea0">4</item>
      <item id="140c8fad-2d93-4b77-b548-5a150f350d81">6</item>
      <item id="5ca365ac-43dd-41fa-9fa7-6237971576aa">7</item>
      <item id="6ac7bb94-88cd-442e-8c3b-933ca3d53fb5">8</item>
      <item id="3cc77134-77ee-4405-bf33-92e6dc7bfdc1">9</item>
    </output>
    

    and so on.