View source with raw comments or as raw
   1/*  Part of SWI-Prolog
   2
   3    Author:        Jan Wielemaker
   4    E-mail:        J.Wielemaker@vu.nl
   5    WWW:           http://www.swi-prolog.org
   6    Copyright (c)  2004-2015, University of Amsterdam
   7    All rights reserved.
   8
   9    Redistribution and use in source and binary forms, with or without
  10    modification, are permitted provided that the following conditions
  11    are met:
  12
  13    1. Redistributions of source code must retain the above copyright
  14       notice, this list of conditions and the following disclaimer.
  15
  16    2. Redistributions in binary form must reproduce the above copyright
  17       notice, this list of conditions and the following disclaimer in
  18       the documentation and/or other materials provided with the
  19       distribution.
  20
  21    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  29    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32    POSSIBILITY OF SUCH DAMAGE.
  33*/
  34
  35:- module(xsdp_type,
  36          [ xsdp_type/1,                % ?Type
  37            xsdp_uri_type/2,            % ?URI, ?Type
  38            xsdp_numeric_uri/2,         % ?URI, ?Primary
  39            xsdp_subtype_of/2,          % ?Type, ?Super
  40            xsdp_convert/3              % +Type, +Content, -Value
  41          ]).
  42
  43
  44/** <module> XML-Schema primitive types
  45
  46This  modules  provides  support  for  the  primitive  XML-Schema  (XSD)
  47datatypes. It defines the type hierarchy which allows for reasoning over
  48types as well as xsdp_convert/3 to  convert   XML  content  to a natural
  49Prolog representation of the XSD type.
  50
  51Based on the W3C definitions at
  52
  53        * http://www.w3.org/TR/xmlschema-2/#built-in-datatypes
  54
  55The current implementation is incomplete and only  there to test the API
  56and its integration with rdf:dataType=Type handling in the RDF parser.
  57
  58The extra 'p' in the module  prefix  (xsdp_*)   is  used  to allow for a
  59module xsd_*, providing full  user-defined  XSD   types  on  top of this
  60module.
  61*/
  62
  63ns('http://www.w3.org/2001/XMLSchema#').
  64
  65
  66                 /*******************************
  67                 *    PRIMITIVE TYPE HIERARCHY  *
  68                 *******************************/
  69
  70%!  xsdp_type(?Type)
  71%
  72%   Test/generate the names for the XML schema primitive types
  73
  74xsdp_type(Type) :-
  75    subtype_of(Type, _).
  76
  77%!  xsdp_uri_type(?URI, ?Type)
  78%
  79%   True if URI is the URI for the the XML-Schema primitive Type.
  80
  81xsdp_uri_type(URI, Type) :-
  82    xsd_local_id(URI, Type),
  83    subtype_of(Type, _).
  84
  85%!  xsdp_subtype_of(?Type, ?Super)
  86%
  87%   True if Type is a (transitive) subtype of Super.
  88
  89xsdp_subtype_of(Type, Type).
  90xsdp_subtype_of(Type, Super) :-
  91    (   nonvar(Type)
  92    ->  subtype_of(Type, Super0),
  93        Super0 \== (-),
  94        xsdp_subtype_of(Super0, Super)
  95    ;   subtype_of(Sub0, Super),
  96        xsdp_subtype_of(Type, Sub0)
  97    ).
  98
  99subtype_of(anyType,            -).
 100subtype_of(anySimpleType,      anyType).
 101                                        % string hierarchy
 102subtype_of(string,             anySimpleType).
 103subtype_of(normalizedString,   string).
 104subtype_of(token,              normalizedString).
 105subtype_of(language,           token).
 106subtype_of('Name',             token).
 107subtype_of('NCName',           'Name').
 108subtype_of('NMTOKEN',          token).
 109subtype_of('NMTOKENS',         'NMTOKEN').
 110subtype_of('ID',               'NCName').
 111subtype_of('IDREF',            'NCName').
 112subtype_of('IDREFS',           'IDREF').
 113subtype_of('ENTITY',           'NCName').
 114subtype_of('ENTITIES',         'ENTITY').
 115                                        % numeric hierarchy
 116subtype_of(decimal,            anySimpleType).
 117subtype_of(integer,            decimal).
 118subtype_of(nonPositiveInteger, integer).
 119subtype_of(negativeInteger,    nonPositiveInteger).
 120subtype_of(long,               integer).
 121subtype_of(int,                long).
 122subtype_of(short,              int).
 123subtype_of(byte,               short).
 124subtype_of(nonNegativeInteger, integer).
 125subtype_of(unsignedLong,       nonNegativeInteger).
 126subtype_of(positiveInteger,    nonNegativeInteger).
 127subtype_of(unsignedInt,        unsignedLong).
 128subtype_of(unsignedShort,      unsignedInt).
 129subtype_of(unsignedByte,       unsignedShort).
 130                                        % other simple types
 131subtype_of(duration,           anySimpleType).
 132subtype_of(dateTime,           anySimpleType).
 133subtype_of(time,               anySimpleType).
 134subtype_of(date,               anySimpleType).
 135subtype_of(gYearMonth,         anySimpleType).
 136subtype_of(gYear,              anySimpleType).
 137subtype_of(gMonthDay,          anySimpleType).
 138subtype_of(gDay,               anySimpleType).
 139subtype_of(gMonth,             anySimpleType).
 140subtype_of(boolean,            anySimpleType).
 141subtype_of(base64Binary,       anySimpleType).
 142subtype_of(hexBinary,          anySimpleType).
 143subtype_of(float,              anySimpleType).
 144subtype_of(double,             anySimpleType).
 145subtype_of(anyURI,             anySimpleType).
 146subtype_of('QName',            anySimpleType).
 147subtype_of('NOTATION',         anySimpleType).
 148
 149%!  xsdp_numeric_uri(?URI, -PromoteURI) is nondet.
 150%
 151%   Table mapping all XML-Schema numeric  URIs   into  the type they
 152%   promote to. Types are promoted   to =integer=, =float=, =double=
 153%   and =decimal=.
 154
 155term_expansion(integer_types, Clauses) :-
 156    findall(integer_type(Type), xsdp_subtype_of(Type, integer), Clauses).
 157term_expansion(xsd_local_ids, Clauses) :-
 158    ns(NS),
 159    findall(xsd_local_id(URI, Type),
 160            (   xsdp_type(Type),
 161                atom_concat(NS, Type, URI)
 162            ),
 163            Clauses).
 164term_expansion(numeric_uirs, Clauses) :-
 165    findall(xsdp_numeric_uri(URI, PrimaryURI),
 166            (   (   integer_type(Type),     Primary = integer
 167                ;   Type = float,           Primary = float
 168                ;   Type = double,          Primary = double
 169                ;   Type = decimal,         Primary = decimal
 170                ),
 171                xsd_local_id(URI, Type),
 172                xsd_local_id(PrimaryURI, Primary)
 173            ),
 174            Clauses).
 175
 176integer_types.
 177xsd_local_ids.
 178
 179numeric_uirs.
 180
 181%!  xsdp_convert(+Type, +Content, -Value)
 182%
 183%   Convert the content model Content to an  object of the given XSD
 184%   type and return the Prolog value in Value.
 185
 186xsdp_convert(URI, Content, Value) :-
 187    (   xsd_local_id(URI, Type)
 188    ->  convert(Type, Content, Value)
 189    ;   convert(URI, Content, Value)
 190    ).
 191
 192convert(anyType, Term, Term) :- !.
 193convert(anySimpleType, [Simple], Simple) :- !.
 194                                        % strings
 195convert(string, [String], String) :- !.
 196                                        % numbers
 197convert(IntType, [Text], Integer) :-
 198    integer_type(IntType),
 199    !,
 200    atom_number(Text, Integer),
 201    (   integer(Integer),
 202        validate_int_domain(IntType, Integer)
 203    ->  true
 204    ;   throw(error(domain_error(Text, IntType), _))
 205    ).
 206convert(float, [Text], Float) :-
 207    !,
 208    atom_number(Text, Number),
 209    Float is float(Number).
 210convert(double, [Text], Float) :-
 211    !,
 212    atom_number(Text, Number),
 213    Float is float(Number).
 214convert(_Any, [X], X) :- !.             % TBD: provide for more types
 215convert(_Any, X, X).
 216
 217validate_int_domain(integer, _).
 218validate_int_domain(int, _).
 219validate_int_domain(long, _).
 220validate_int_domain(nonPositiveInteger, I) :- \+ I > 0.
 221validate_int_domain(negativeInteger, I) :-    I < 0.
 222validate_int_domain(short, I) :-              between(-32768, 32767, I).
 223validate_int_domain(byte,  I) :-              between(-128, 127, I).
 224validate_int_domain(nonNegativeInteger, I) :- \+ I < 0.
 225validate_int_domain(unsignedLong,       I) :- I >= 0.
 226validate_int_domain(positiveInteger,    I) :- I > 0.
 227validate_int_domain(unsignedInt,        I) :- I >= 0.
 228validate_int_domain(unsignedShort,      I) :- between(0, 65535, I).
 229validate_int_domain(unsignedByte,       I) :- between(0, 255, I).