Testing that a value is a UUID

Thursday, 3 November 2022 · 5 messages · last reply 5 Nov 2022
MH
Martin Honnenin reply to Graydon Saunders, 3 Nov 2022, 21:003 Nov 2022 20:17 #
Quoted text · Graydon Saunders · 16 lines
On 11/3/2022 8:00 PM, Graydon Saunders wrote: > > > You can (I think) test if some attribute value is an RFC 4122 UUID by > using a regular expression: > > let $regexp as xs:string := > '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-5][0-9a-fA-F]{3}-[089abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$' > > for $uuid in //@GUID > let $value as xs:string := $uuid/string() > where not(matches($value,$regexp)) > return $value > > Is there a better way to do this? >
I wondered whether Java has a class or method that could help and tried
declare namespace uuid = "java:java.util.UUID";

declare function local:isUUID($uuid as xs:string) as xs:boolean {
   try {
     let $uuidJava := uuid:fromString($uuid)
     return true()
   } catch * {
     false()
   }
};
("123e4567-e89b-12d3-a456-9AC7CBDCEE52", "123e4567-h89b-12d3-a456-9AC7CBDCEE52") ! local:isUUID(.) Note I haven't checked whether Java implements the RFC you mention.
GS
Graydon Saunders3 Nov 2022 21:00 #
Hello -- You can (I think) test if some attribute value is an RFC 4122 UUID by using a regular expression: let $regexp as xs:string := '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-5][0-9a-fA-F]{3}-[089abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$'
for $uuid in //@GUID
  let $value as xs:string := $uuid/string()
  where not(matches($value,$regexp))
  return $value
Is there a better way to do this? thanks! Graydon
G
Graydonin reply to Martin Honnen, 3 Nov 2022, 20:173 Nov 2022 21:55 #
Quoted text · Graydon Saunders · 19 lines
On Thu, Nov 03, 2022 at 08:17:51PM +0100, Martin Honnen scripsit: > On 11/3/2022 8:00 PM, Graydon Saunders wrote: > > Is there a better way to [test if a value is a UUID]? > > > I wondered whether Java has a class or method that could help and tried > > declare namespace uuid = "java:java.util.UUID"; > > declare function local:isUUID($uuid as xs:string) as xs:boolean { > try { > let $uuidJava := uuid:fromString($uuid) > return true() > } catch * { > false() > } > }; > > ("123e4567-e89b-12d3-a456-9AC7CBDCEE52", > "123e4567-h89b-12d3-a456-9AC7CBDCEE52") ! local:isUUID(.)
That works for me; thank you!
Quoted text · Martin Honnen · 1 line
> Note I haven't checked whether Java implements the RFC you mention.
This is much more tidy and gets the same answer the regular expression test does, so I'm thinking it's an improvement. Thank you!
-- Graydon Saunders | graydonish at gmail.com Þæs oferéode, ðisses swá mæg. -- Deor ("That passed, so may this.")
LQ
Liam R. E. Quinin reply to Graydon Saunders, 3 Nov 2022, 21:004 Nov 2022 00:13 #
Quoted text · Graydon Saunders · 10 lines
On Thu, 2022-11-03 at 15:00 -0400, Graydon Saunders wrote: > Hello -- > > You can (I think) test if some attribute value is an RFC 4122 UUID by > using > a regular expression: > > let $regexp as xs:string := > '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-5][0-9a-fA-F]{3}-[089abAB][0-9a- > fA-F]{3}-[0-9a-fA-F]{12}$'
You could also split this up into strings, maybe using a helper function:
let $hexdigit := '[0-9a-f]',
    $n := function($n as xs:integer) {
      $hexdigit || '{' || $n || '}'
    },
    $matchuuid := '^'
    || $n(8)
    || '-'
    || $n(4)
    || '-'
    || '[0-5]'
    || $n($3)
    || '-'
    || '[098ab]'
    || $n{3}
    || '-'
    || $n{12}
and use it with the case insensitive "i" flag. However, this isn't very clear. Mike Kay gives a solution [1], translate($in, '0123456789abcdefABCDEF', '000000000000000000000000') = '00000000-0000-0000-0000-000000000000' which is probably enough in practice. If you need to check further, see RFC 4122 for the components. Your regexp limits the UUID value space https://datatracker.ietf.org/doc/html/rfc4122#page-5 [1] https://p2p.wrox.com/xslt/68464-validate-guid-uuid.html
-- Liam Quin, https://www.delightfulcomputing.com/ Available for XML/Document/Information Architecture/XSLT/ XSL/XQuery/Web/Text Processing/A11Y training, work & consulting. Barefoot Web-slave, antique illustrations: http://www.fromoldbooks.org
G
Graydon5 Nov 2022 05:54 #
[had to fish this one out of spam]
Quoted text · Graydon Saunders · 8 lines
On Thu, Nov 03, 2022 at 06:12:02PM -0400, Liam R. E. Quin scripsit: > On Thu, 2022-11-03 at 15:00 -0400, Graydon Saunders wrote: > > You can (I think) test if some attribute value is an RFC 4122 UUID by using > > a regular expression: > > > > let $regexp as xs:string := > > '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-5][0-9a-fA-F]{3}-[089abAB][0-9a- > > fA-F]{3}-[0-9a-fA-F]{12}$'
[snip more structured approach to writing the regular expression]
Quoted text · Liam R. E. Quin · 6 lines
> Mike Kay gives a solution [1], > > translate($in, '0123456789abcdefABCDEF', '000000000000000000000000') = > '00000000-0000-0000-0000-000000000000' > > which is probably enough in practice.
Elegant! thank you! That's probably the least expensive one yet.
Quoted text · Liam R. E. Quin · 5 lines
> If you need to check further, see RFC 4122 for the components. > Your regexp limits the UUID value space > https://datatracker.ietf.org/doc/html/rfc4122#page-5 > > [1] https://p2p.wrox.com/xslt/68464-validate-guid-uuid.html
Noted, thank you! (I am thankfully at the proof-of-concept stage.)
-- Graydon Saunders | graydonish at gmail.com Þæs oferéode, ðisses swá mæg. -- Deor ("That passed, so may this.")

⚡Generated with XQuery