Làm cách nào để tạo UUID bằng XSLT thuần túy? Về cơ bản tìm kiếm một cách để tạo ra các chuỗi duy nhất với XSLT. Trình tự có thể dài bất kỳ.XSLT tạo UUID
Tôi đang sử dụng XSLT 2.0.
Làm cách nào để tạo UUID bằng XSLT thuần túy? Về cơ bản tìm kiếm một cách để tạo ra các chuỗi duy nhất với XSLT. Trình tự có thể dài bất kỳ.XSLT tạo UUID
Tôi đang sử dụng XSLT 2.0.
Kể từ XSLT là một ngôn ngữ chức năng, tạo ra số ngẫu nhiên không phải là một phần của ngôn ngữ. Điều đó nói rằng, có các gói mở rộng (EXSLT) và một số bộ xử lý (Saxon) hỗ trợ việc tạo ra các số ngẫu nhiên. Nếu bạn không thể sử dụng tiện ích mở rộng hoặc Saxon, thì tôi tin rằng bạn không may mắn.
Đây là số good example. Về cơ bản bạn thiết lập một phần mở rộng trỏ đến lớp UUID java, và sau đó tham khảo nó trong 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>
Xin lỗi, vì không làm rõ. Tôi đã thấy ví dụ đó trước nhưng nó cần phải được thực hiện trong XSLT thuần túy. Không có Java. – Ayyoudy
'xsl: value-of' không thể là con của' xsl: stylesheet' ... – Abel
Tôi đã upvoted vì điều này làm việc cho tôi. Tuy nhiên, đáng chú ý là các cuộc gọi java phản xạ như thế này cũng không có sẵn cho các giấy phép Saxon HE (mặc dù như những người khác đã lưu ý, nó ít nhiều là một vấn đề được giải quyết để viết các chức năng của riêng bạn để làm điều đó). –
Hãy xem một câu hỏi khác Generate GUID in XSLT.
lẽ this bài viết sẽ giúp bạn - có chức năng XSLT được xác định để tạo ra GUID
Đối tạo số ngẫu nhiên trong XSLT, xem Casting the Dice with FXSL: Random Number Generation Functions in XSLT. Hàm mở rộng duy nhất mà nó sử dụng là nút-set(), không còn cần thiết trong XSLT 2.0 nữa.
Ngoài ra, nếu yêu cầu chỉ là các ID là duy nhất (không nhất thiết là ngẫu nhiên), hãy xem how to generate unique string. Ví dụ: nếu bạn đang tạo UUID cho từng phần tử của tài liệu XML đầu vào, bạn có thể sử dụng kết hợp URL của tài liệu đầu vào và <xsl:number>
để tạo chuỗi duy nhất cho mỗi phần tử.
Bạn có thể sử dụng đoạn mã XSLT cho điều này (nguồn: 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 ... thank bạn :) – Ayyoudy
Cảm ơn bạn đã chia sẻ. Nguồn (public-contract-ontology) là một liên kết chết: ( –
Có thể nhận được 4 UUID khác nhau với mã này "
Nếu sử dụng .Net
's XslCompiledTransform
chuyển đổi XSL, bạn có thể thiết lập các EnableScripts
tài sản để true
, sau đó sử dụng mã như bên dưới :
<msxsl:script language="C#" implements-prefix="csharp">
<![CDATA[
public static string NewGuid()
{
return Guid.NewGuid().ToString();
}
]]>
</msxsl:script>
NB: Tôi đã cung cấp chức năng tùy chỉnh này tên/tiền tố csharp
ở trên; nhưng bạn có thể gọi nó là bất cứ điều gì bạn thích.
Để biết thêm về cách bật tập lệnh, hãy xem https://stackoverflow.com/a/1873265/361842.
Full tập tin XSLT dưới đây để đưa ra một số bối cảnh bổ sung:
<?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>
thể trùng lặp của [Tạo GUID trong XSLT] (http://stackoverflow.com/questions/5494175/generate-guid-in-xslt) –