Search code examples
xsdrdfowljson-ldrdfs

How should I define my own restricted types in an RDF vocab?


I'd like to define my custom restricted types for my own RDF vocab.

For example if I want a string that cannot be longer than 20 characters, then I can do something like this with XSD in XML:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema  xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:simpleType name="Char_20">
        <xs:restriction base="xs:string">
            <xs:minLength value="1"/>
            <xs:maxLength value="20"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

I found something similar with OWL facets and XSD in turtle:

:EquipmentCategoryName
    rdf:type owl:DatatypeProperty
    rdfs:domain :EquipmentCategory
    rdfs:range [
        rdf:type rdfs:Datatype
        owl:onDatatype xsd:string
        owl:withRestrictions (
            [
                xsd:maxLength "10"^^xsd:int
            ]
        )
    ]

In theory I could even use my:Char_20 rdfs:subClassOf xsd:string to describe my restricted type, but I guess that would not be a standard solution.

I checked schema.org and it is a complete surprise. https://schema.org/version/6.0/schema.jsonld They add XSD to the context, but they don't even bother to define any XSD primitive based types or give the XSD range properly. And that is the vocab everybody uses.

So I see a complete chaos in this area. Is there any standard or recommended solution to define my own restricted types?


Solution

  • I checked many vocabs here: https://github.com/ruby-rdf/rdf-vocab/ and on different pages and read more about OWL on W3C sites. It turned out we can use XSD primitives as we use RDF classes. A typical usage is the following:

    by properties

    Y rdf:type rdfs:Class
    x rdf:type rdfs:Property
    x rdfs:range xsd:integer
    x rdfs:domain Y
    
    y rdf:type Y
    y x 12
    

    by variables

    x rdf:type xsd:integer
    x rdf:value 12
    

    To restrict the integer to the 0-100 range first we need to define a restriction. This is tricky, because we have to define the range too:

    r rdf:type owl:Restriction
    r owl:allValuesFrom s
    s rdf:type owl:DataRange
    s rdf:onDataRange xsd:integer
    s xsd:minInclusive 0
    s xsd:maxInclusive 100
    

    If we want to apply the restriction to our property we need to do the following

    x rdf:type owl:DatatypeProperty
    r owl:onProperty x
    r owl:onClass Y
    

    If we want to apply it to our variable that is a different strory. I am not entirely sure about this, but I think we can define a custom restricted primitive type this way:

    xsd:integer rdf:type rdfs:Datatype
    
    X rdf:type rdfs:Datatype
    X rdfs:subClassOf xsd:integer
    r owl:onDatatype X
    

    After we have our new type we just use it for the variable:

    x rdf:type X
    x rdf:value 12
    

    If so we can use the same approach for the property too:

    Y rdf:type rdfs:Class
    x rdf:type rdfs:Property
    x rdfs:range X
    x rdfs:domain Y
    
    y rdf:type Y
    y x 12