Come posso generare un UUID con XSLT puro? Fondamentalmente alla ricerca di un modo per creare sequenze uniche con XSLT. La sequenza può essere di qualsiasi lunghezza.XSLT genera UUID
Sto utilizzando XSLT 2.0.
Come posso generare un UUID con XSLT puro? Fondamentalmente alla ricerca di un modo per creare sequenze uniche con XSLT. La sequenza può essere di qualsiasi lunghezza.XSLT genera UUID
Sto utilizzando XSLT 2.0.
Poiché XSLT è un linguaggio funzionale, generare numeri casuali non è parte del linguaggio. Detto questo, ci sono pacchetti di estensione (EXSLT) e alcuni processori (Saxon) che supportano la generazione di numeri casuali. Se non puoi usare estensioni o Saxon, allora credo che tu sia sfortunato.
In che modo Saxon supporta la generazione di un numero casuale? – Ayyoudy
Saxon viene fornito con il modulo casuale EXSLT integrato. Vedi http://saxonica.com/documentation/extensions/intro.xml –
Grazie. Peccato che i moduli EXSLT integrati non siano disponibili per Saxon HE (Home Edition). – Ayyoudy
Ecco un good example. Fondamentalmente si imposta un'estensione che punta alla classe UUID Java, e quindi fare riferimento nella XSL:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:uuid="java:java.util.UUID">
<xsl:template match="/">
<xsl:variable name="uid" select="uuid:randomUUID()"/>
<xsl:value-of select="$uid"/>
</xsl:template>
Ci scusiamo per non aver chiarito. Ho visto questo esempio prima, ma deve essere fatto in XSLT puro. No Java. – Ayyoudy
'xsl: value-of' non può essere un figlio di' xsl: stylesheet' ... – Abel
Ho upvoted come questo ha funzionato per me. Tuttavia, vale la pena notare che chiamate java riflessive come questa non sono disponibili per le licenze Saxon HE (sebbene, come altri hanno notato, è più o meno un problema risolto scrivere le proprie funzioni per farlo). –
Date un'occhiata ad un'altra domanda Generate GUID in XSLT.
Probabilmente this articolo vi aiuterà - non funzioni XSLT definiti per generare GUID
per generare numeri casuali in XSLT, vedere Casting the Dice with FXSL: Random Number Generation Functions in XSLT. L'unica funzione di estensione che utilizza è node-set(), che non è più necessaria in XSLT 2.0.
Inoltre, se il requisito è solo che gli ID siano univoci (non necessariamente casuale), dare un'occhiata a how to generate unique string. Ad esempio, se si genera un UUID per ciascun elemento di un documento XML di input, è possibile utilizzare una combinazione dell'URL del documento di input e <xsl:number>
per generare una stringa univoca per ciascun elemento.
È possibile utilizzare frammento XSLT per questa (fonte: http://code.google.com/p/public-contracts-ontology/source/browse/transformers/GB-notices/uuid.xslt?r=66e1d39a1c140079a86d219df5b3e031007cc957):
<xsl:stylesheet xmlns:uuid="http://www.uuid.org" xmlns:math="http://exslt.org/math" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/">
<xsl:value-of select="
concat('First random ID:', uuid:get-id()),
concat('Base timestamp: ', uuid:generate-timestamp()),
concat('Clock id: ' ,uuid:generate-clock-id()),
concat('Network node: ' ,uuid:get-network-node()),
concat('UUID Version: ' ,uuid:get-uuid-version()),
concat('Generated UUID: ' ,uuid:get-uuid()),
concat('Generated UUID: ' ,uuid:get-uuid()),
concat('Generated UUID: ' ,uuid:get-uuid()),
concat('Generated UUID: ' ,uuid:get-uuid())
" separator=" "/>
</xsl:template>
<!--
Functions in the uuid: namespace are used to calculate a UUID
The method used is a derived timestamp method, which is explained
here: http://www.famkruithof.net/guid-uuid-timebased.html
and here: http://www.ietf.org/rfc/rfc4122.txt
-->
<!--
Returns the UUID
-->
<xsl:function name="uuid:get-uuid" as="xs:string*">
<xsl:variable name="ts" select="uuid:ts-to-hex(uuid:generate-timestamp())"/>
<xsl:value-of separator="-" select="
substring($ts, 8, 8),
substring($ts, 4, 4),
string-join((uuid:get-uuid-version(), substring($ts, 1, 3)), ''),
uuid:generate-clock-id(),
uuid:get-network-node()"/>
</xsl:function>
<!--
internal aux. fu
with saxon, this creates a more-unique result with
generate-id then when just using a variable containing a node
-->
<xsl:function name="uuid:_get-node">
<xsl:comment/>
</xsl:function>
<!-- generates some kind of unique id -->
<xsl:function name="uuid:get-id" as="xs:string">
<xsl:sequence select="generate-id(uuid:_get-node())"/>
</xsl:function>
<!--
should return the next nr in sequence, but this can't be done
in xslt. Instead, it returns a guaranteed unique number
-->
<xsl:function name="uuid:next-nr" as="xs:integer">
<xsl:variable name="node">
<xsl:comment/>
</xsl:variable>
<xsl:sequence select="
xs:integer(replace(
generate-id($node), '\D', ''))"/>
</xsl:function>
<!-- internal fu for returning hex digits only -->
<xsl:function name="uuid:_hex-only" as="xs:string">
<xsl:param name="string"/>
<xsl:param name="count"/>
<xsl:sequence select="
substring(replace(
$string, '[^0-9a-fA-F]', '')
, 1, $count)"/>
</xsl:function>
<!-- may as well be defined as returning the same seq each time -->
<xsl:variable name="_clock" select="uuid:get-id()"/>
<xsl:function name="uuid:generate-clock-id" as="xs:string">
<xsl:sequence select="uuid:_hex-only($_clock, 4)"/>
</xsl:function>
<!--
returns the network node, this one is 'random', but must
be the same within calls. The least-significant bit must be '1'
when it is not a real MAC address (in this case it is set to '1')
-->
<xsl:function name="uuid:get-network-node" as="xs:string">
<xsl:sequence select="uuid:_hex-only('09-17-3F-13-E4-C5', 12)"/>
</xsl:function>
<!-- returns version, for timestamp uuids, this is "1" -->
<xsl:function name="uuid:get-uuid-version" as="xs:string">
<xsl:sequence select="'1'"/>
</xsl:function>
<!--
Generates a timestamp of the amount of 100 nanosecond
intervals from 15 October 1582, in UTC time.
-->
<xsl:function name="uuid:generate-timestamp">
<!--
date calculation automatically goes
correct when you add the timezone information, in this
case that is UTC.
-->
<xsl:variable name="duration-from-1582" as="xs:dayTimeDuration">
<xsl:sequence select="
current-dateTime() -
xs:dateTime('1582-10-15T00:00:00.000Z')"/>
</xsl:variable>
<xsl:variable name="random-offset" as="xs:integer">
<xsl:sequence select="uuid:next-nr() mod 10000"/>
</xsl:variable>
<!-- do the math to get the 100 nano second intervals -->
<xsl:sequence select="
(days-from-duration($duration-from-1582) * 24 * 60 * 60 +
hours-from-duration($duration-from-1582) * 60 * 60 +
minutes-from-duration($duration-from-1582) * 60 +
seconds-from-duration($duration-from-1582)) * 1000
* 10000 + $random-offset"/>
</xsl:function>
<!-- simple non-generalized function to convert from timestamp to hex -->
<xsl:function name="uuid:ts-to-hex">
<xsl:param name="dec-val"/>
<xsl:value-of separator="" select="
for $i in 1 to 15
return (0 to 9, tokenize('A B C D E F', ' '))
[
$dec-val idiv
xs:integer(math:power(16, 15 - $i))
mod 16 + 1
]"/>
</xsl:function>
<xsl:function name="math:power">
<xsl:param name="base"/>
<xsl:param name="power"/>
<xsl:choose>
<xsl:when test="$power < 0 or contains(string($power), '.')">
<xsl:message terminate="yes">
The XSLT template math:power doesn't support negative or
fractional arguments.
</xsl:message>
<xsl:text>NaN</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="math:_power">
<xsl:with-param name="base" select="$base"/>
<xsl:with-param name="power" select="$power"/>
<xsl:with-param name="result" select="1"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:template name="math:_power">
<xsl:param name="base"/>
<xsl:param name="power"/>
<xsl:param name="result"/>
<xsl:choose>
<xsl:when test="$power = 0">
<xsl:value-of select="$result"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="math:_power">
<xsl:with-param name="base" select="$base"/>
<xsl:with-param name="power" select="$power - 1"/>
<xsl:with-param name="result" select="$result * $base"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>:choose>
</xsl:template>
</xsl:stylesheet>
upvoted ... grazie you :) – Ayyoudy
Grazie per aver condiviso. La fonte (ontologia dei contratti pubblici) è un collegamento morto :( –
È possibile ottenere 4 UUID diversi con questo codice "
Se si utilizza .Net
s' XslCompiledTransform
per trasformare la vostra XSL, è possibile impostare la proprietà EnableScripts
a true
, quindi utilizzare il codice, come di seguito :
<msxsl:script language="C#" implements-prefix="csharp">
<![CDATA[
public static string NewGuid()
{
return Guid.NewGuid().ToString();
}
]]>
</msxsl:script>
NB: ho dato questa funzionalità personalizzate il nome/prefisso csharp
in quanto sopra; ma puoi chiamarlo come preferisci.
Per ulteriori sull'abilitazione script, vedere https://stackoverflow.com/a/1873265/361842.
file XSLT completa qui sotto per dare un po 'di contesto aggiuntivo:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:csharp="urn:JohnLBevan/NewGuid"
exclude-result-prefixes="xsl msxsl csharp"
>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//*/text()">
<!-- replaces all text nodes from input document with GUIDs -->
<xsl:value-of select="csharp:NewGuid()"/>
</xsl:template>
<msxsl:script language="C#" implements-prefix="csharp">
<![CDATA[
public static string NewGuid()
{
return Guid.NewGuid().ToString();
}
]]>
</msxsl:script>
</xsl:stylesheet>
possibile duplicato del [Genera GUID in XSLT] (http://stackoverflow.com/questions/5494175/generate-guid-in-xslt) –