Re: Question on value based constraints

Irene, all,

thanks a lot for these examples. It seems that SHACL is very good at
mapping XML constraints to RDF constraints. Has this been a use case in the
development of SHACL, and is there even a best practice document for such
mappings?

Disclaimer: a while ago I tried to push the topic of RDF & XML mappings in
a different group - the W3C RAX community group. We found a lot of
interest, but no standardized solutions. Using SHACL, a best practice
document on XML constraints mapping could find a larger audience. Just my
two cents.

Regards,

Felix


On Sat, 20 Apr 2019 at 22:57, Irene Polikoff <irene@topquadrant.com> wrote:

> Yes, I would also favor translating this XML into
>
> > :p1 :simpleAddress “....xyz...” .
> > :p2 :complexAddress [ a :ComplexAddress; :street ... ] ;
>
> The next question is then what do you want to enforce with SHACL.
>
> You could do:
>
> sh:or (
>                 [
>                         sh:path ex:simpleAddress ;
>                         sh:datatype xsd:string ;
>                 ]
>                 [
>                         sh:path ex:complexAddress ;
>                         sh:class ex:ComplexAddress ;
>                 ]
>         ) .
>
> This will allow multiple addresses. It will also allow a person to have
> one or more complex addresses and one or more simple addresses. And it will
> not require that a person has an address. Your XML did not have any
> restrictions either way.
>
> Let’s say, you want to ensure that at least one address exists and
> addresses could be either simple or complex.
>
> You can then do
>
> sh:or (
>                 [
>                         sh:path ex:simpleAddress ;
>                         sh:datatype xsd:string ;
>                         sh:minCount 1 ;
>                 ]
>                 [
>                         sh:path ex:complexAddress ;
>                         sh:class ex:ComplexAddress ;
>                         sh:minCount 1 ;
>                 ]
>         ) .
>
> This is, of course, only a fragment. The shape would be something like:
>
> ex:Person a owl:Class, sh:NodeShape;
> sh:or (
>                 [
>                         sh:path ex:simpleAddress ;
>                         sh:datatype xsd:string ;
>                         sh:minCount 1 ;
>                 ]
>                 [
>                         sh:path ex:complexAddress ;
>                         sh:class ex:ComplexAddress ;
>                         sh:minCount 1 ;
>                 ]
>         ) ;
> sh:property [ sh:path -> some other declarations e.g., about a name, etc.];
>
> ...
>
> Or if you want separate shapes from classes, then you could do
>
> ex:PersonShape a sh:NodeShape;
> sh:classTarget ex:Person;
> ...
>
> If you want to ensure that at least one address exists and people who have
> complex addresses do not have simple addresses and vice versa, then you can
> do
>
>
> sh:xone (
>                 [
>                         sh:path ex:simpleAddress ;
>                         sh:datatype xsd:string ;
>                         sh:minCount 1 ;
>                 ]
>                 [
>                         sh:path ex:complexAddress ;
>                         sh:class ex:ComplexAddress ;
>                         sh:minCount 1 ;
>                 ]
>         ) .
>
>
> If we do not need to insist on the presence of at least one address, but
> still want to ensure that people who have complex addresses do not have
> simple addresses, then you can do:
>
> sh:xone (
>                 [
>                         sh:path ex:simpleAddress ;
>                         sh:datatype xsd:string ;
>                 ]
>                 [
>                         sh:path ex:complexAddress ;
>                         sh:class ex:ComplexAddress ;
>                 ]
>         ) .
>
> Or you could do the following which would mean the same and avoid using
> sh:xone:
>
> ex:Person a owl:Class, sh:NodeShape;
> sh:property [
>                 sh:path ex:simpleAddress ;
>                 sh:datatype xsd:string ;
>                 sh:disjoint ex:complexAddress;
>         ] ;
> sh:property [
>                 sh:path ex:complexAddress ;
>                 sh:class ex:ComplexAddress ;
>                 sh:disjoint ex:simpleAddress;
>         ] .
>
> If you want to make certain that there is no more than one address and it
> could be either simple or complex, then you can do:
>
> sh:xone (
>                 [
>                         sh:path ex:simpleAddress ;
>                         sh:datatype xsd:string ;
>                         sh:maxCount 1 ;
>                 ]
>                 [
>                         sh:path ex:complexAddress ;
>                         sh:class ex:ComplexAddress ;
>                         sh:maxCount 1 ;
>                 ]
>         ) .
>
> Or
>
> sh:property [
>                 sh:path ex:simpleAddress ;
>                 sh:datatype xsd:string ;
>                 sh:maxCount 1 ;
>                 sh:disjoint ex:complexAddress;
>         ] ;
> sh:property [
>                 sh:path ex:complexAddress ;
>                 sh:class ex:ComplexAddress ;
>                 sh:maxCount 1 ;
>                 sh:disjoint ex:simpleAddress;
>         ] .
>
> And if you want to say that there has to be exactly one address which
> could be either simple or complex, then do:
>
> sh:xone (
>                 [
>                         sh:path ex:simpleAddress ;
>                         sh:datatype xsd:string ;
>                         sh:maxCount 1 ;
>                         sh:minCount 1 ;
>                 ]
>                 [
>                         sh:path ex:complexAddress ;
>                         sh:class ex:ComplexAddress ;
>                         sh:maxCount 1 ;
>                         sh:minCount 1 ;
>                 ]
>         ) .
>
> > On Apr 20, 2019, at 12:39 PM, Håvard M. Ottestad <hmottestad@gmail.com>
> wrote:
> >
> > Personally I would prefer to convert that to:
> >
> > :p1 :simpleAddress “....xyz...” .
> > :p2 :complexAddress [ a :ComplexAddress; :street ... ] ;
> >
> > And have a simple RDFS property hierarchy:
> >  - address
> >  - - simpleAddress
> >  - - complexAddress
> >
> > Håvard
> >
> > On 20 Apr 2019, at 16:09, Felix Sasaki <felix@sasakiatcf.com> wrote:
> >
> >> Dear all,
> >>
> >> this discussion is very helpful for me to better understand SHACL.
> Below is more background on my use case.
> >>
> >> I want to map XML structures to RDF. The goal is not to do a full
> mapping of an XML based schema; but to map certain definitions to RDF and
> then use SHACL has a kind of "view on XML data".
> >>
> >> One type of constraint that can be expressed via the XML schema
> language "Relax NG" allows to restrict an XML content model based on
> attribute values. So in an XML representation, one may have
> >>
> >> <person id="p1">
> >> <address type="simpleAddress">Street xzy plz 12345</address>
> >> </person>
> >>
> >> versus
> >> <person id="p1">
> >> <address type="complexAddress">
> >> <street>...</street>
> >> <postcode>...</postcode>
> >> </address>
> >> </person>
> >>
> >> here, the value of the "type" attributes constraints the allowed
> structure of the XML substructure: text only versus a specific element
> content model.
> >>
> >> I had not thought about the case that there could be several addresses,
> and each of them could have a different type. So Irene's solutions may be
> what I am looking for ... on the other hand, with that solution (= without
> sh:Xone), I am not sure how to implement the "trigger a shacl shape by a
> literal value" functionality.
> >>
> >> Regards,
> >>
> >> Felix
> >>
> >>
> >> On Fri, 19 Apr 2019 at 14:42, Irene Polikoff <irene@topquadrant.com>
> wrote:
> >> It is a bit different, I think.
> >>
> >> :Xone says that the format of addresses of a given person should be
> either simple or complex. A person could have multiple addresses but they
> need to be of the same form.
> >>
> >> This may be a requirement in Felix’s case, but in a more general sense
> it was not obvious to me that this must be a requirement. In other words,
> if a person has two addresses, it is possible that one of them is simple
> and another one is complex.
> >>
> >> To ensure that there is only one address, there still needs to be
> maxCount =1, even if xone is used.
> >>
> >> Of course, with SHACL, there are often multiple ways to express
> requirements that boil down to the same results.
> >>
> >> I have excluded anything about ex:addressType because I thought it was
> a bit peculiar to have such statements on a person. I thought it may be
> possible that Felix was using it only because he thought it would be
> necessary to support his use case.
> >>
> >> So, I wanted to provide an alternative that did not involve such
> statements.
> >>
> >>
> >> Sent from my iPhone
> >>
> >> > On Apr 19, 2019, at 1:01 AM, Simon Steyskal <simon.steyskal@wu.ac.at>
> wrote:
> >> >
> >> > Hi Irene!
> >> >
> >> >> sh:path ex:hasAdress ;
> >> >>  sh:or (
> >> >>      [
> >> >>        sh:datatype xsd:string ;
> >> >>      ]
> >> >>      [
> >> >>        sh:class ex:ComplexAddress ;
> >> >>      ]
> >> >>    ) ;
> >> >> .
> >> >
> >> >
> >> > But this doesn't take the value of ex:addressType into account ->
> >> >
> >> >>> How do I model the choice between the two address' shapes based on
> >> >>> the
> >> >>> values "simpleAddress" vs. "complexAddress"?
> >> >
> >> >> You do not really need xone. If a person can only have one address,
> >> >> then add:
> >> >> sh:maxCount 1 ;
> >> >
> >> > in which case it would be equivalent to sh:xone again, right? ;)
> >> > e.g.,
> >> >
> >> > sh:property [
> >> >    sh:path ex:hasAddress ;
> >> >    sh:maxCount 1 ;
> >> >    sh:or (
> >> >      [
> >> >        sh:datatype xsd:string ;
> >> >      ]
> >> >      [
> >> >        sh:class ex:ComplexAddress ;
> >> >      ]
> >> >    )
> >> > ] .
> >> >
> >> > is just a slightly more verbose version of ->
> >> >
> >> > sh:property [
> >> >    sh:path ex:hasAddress ;
> >> >    sh:xone (
> >> >      [
> >> >        sh:datatype xsd:string ;
> >> >      ]
> >> >      [
> >> >        sh:class ex:ComplexAddress ;
> >> >      ]
> >> >    )
> >> > ] .
> >> >
> >> >
> >> > br, simon
> >> >
> >> > ---
> >> > DDipl.-Ing. Simon Steyskal
> >> > Institute for Information Business, WU Vienna
> >> >
> >> > www: http://www.steyskal.info/  twitter: @simonsteys
> >> >
> >> > Am 2019-04-18 23:51, schrieb Irene Polikoff:
> >> >> Felix,
> >> >> If you want to have a property ex:hasAddress and its values be either
> >> >> a string or a resource which in turn has properties like steel, city,
> >> >> zip, etc., then you can simply use:
> >> >> sh:path ex:hasAdress ;
> >> >>  sh:or (
> >> >>      [
> >> >>        sh:datatype xsd:string ;
> >> >>      ]
> >> >>      [
> >> >>        sh:class ex:ComplexAddress ;
> >> >>      ]
> >> >>    ) ;
> >> >> .
> >> >> You do not really need xone. If a person can only have one address,
> >> >> then add:
> >> >> sh:maxCount 1 ;
> >> >> In this response, I am assuming that your complex addresses look as
> >> >> follows:
> >> >> ex:Address1 ex:ComplexAddress;
> >> >> ex:street “100 Main Street”;
> >> >> ex:city “Any City”;
> >> >> etc.
> >> >> You would then have a shape that checks for validity of complex
> >> >> addresses. This can be done directly on a class (implicit target).
> >> >> For example
> >> >> ex:ComplexAddress a owl:Class, sh:NodeShape;
> >> >> sh:property [
> >> >> sh:path ex:street ;
> >> >> sh:minCount 1
> >> >> sh:datatype xsd:string;];
> >> >> sh:property [
> >> >> sh:path ex:city ;
> >> >> sh:minCount 1
> >> >> sh:datatype xsd:string;];
> >> >> And so on
> >> >> If your complex addresses for some other reason do not have a type
> >> >> statement, then do
> >> >> sh:path ex:hasAdress ;
> >> >>  sh:or (
> >> >>      [
> >> >>        sh:datatype xsd:string ;
> >> >>      ]
> >> >>      [
> >> >>        sh:node ex:ComplexAddressShape ;
> >> >>      ]
> >> >>    ) ;
> >> >> .
> >> >> And also define a shape ex:ComplexAddressShape similar to above as
> >> >> something that has city, street, etc. properties.
> >> >> x:one would be needed if your people could have either
> >> >> ex:streetAddress property or a group of properties
> >> >> ex:city+ex:street+…
> >> >> In other words, there was no intermediate resource to represent
> >> >> complex address.
> >> >> Irene
> >> >>> On Apr 18, 2019, at 1:13 AM, Felix Sasaki <felix@sasakiatcf.com>
> >> >>> wrote:
> >> >>> Perfect, thanks a lot, Simon. This is also in line with what I found
> >> >>> in this tutorial:
> >> >>
> https://de.slideshare.net/mobile/jpcik/rdf-data-validation-2017-shacl
> >> >>> Regards,
> >> >>> Felix
> >> >>> Am Donnerstag, 18. April 2019 schrieb Simon Steyskal
> >> >>> <simon.steyskal@wu.ac.at>:
> >> >>> fwiw, sh:and isn't really necessary though.. is this what you wanted
> >> >>> ->
> >> >>> https://gist.github.com/simonstey/e3add7ff0740dd95a4c80d26840ca3e3
> >> >>> [1] ?
> >> >>> br simon
> >> >>> ---
> >> >>> DDipl.-Ing. Simon Steyskal
> >> >>> Institute for Information Business, WU Vienna
> >> >>> www: http://www.steyskal.info/  twitter: @simonsteys
> >> >>> Am 2019-04-17 18:41, schrieb Simon Steyskal:
> >> >>> Hi!
> >> >>> have you tried combining sh:xone with two sh:and constraints?
> >> >>> e.g. something along the lines of:
> >> >>> sh:xone (
> >> >>> sh:and (
> >> >>> ex:hasAddress sh:datatype xsd:string
> >> >>> ex:addrType sh:hasValue "simple"
> >> >>> )
> >> >>> sh:and (
> >> >>> ex:hasAddress sh:class ex:complexAddr
> >> >>> ex:addrType sh:hasValue "comolex"
> >> >>> )
> >> >>> )
> >> >>> (I'm on mobile right now so just pseudocode)
> >> >>> br simon
> >> >>> -------- Original message --------
> >> >>> From: Felix Sasaki <felix@sasakiatcf.com>
> >> >>> Date: 4/17/19 18:26 (GMT+01:00)
> >> >>> To: public-shacl@w3.org
> >> >>> Subject: Question on value based constraints
> >> >>> HI all,
> >> >>> I have a question on how to model alternative constraints based on
> >> >>> literal values.
> >> >>> Let's assume the two alternatives ways to express an address:
> >> >>> ALTERNATIVE 1:
> >> >>> ex:person1 ex:hasAddress "Street xzy plz 12345 ..."
> >> >>> ex:person1 ex:addressType "simpleAddress".
> >> >>> ALTERNATIVE 2:
> >> >>> ex:person1 ex:hasAddress ex:someComplexAddress1 # object is an
> >> >>> instance of class ex:complexAddress
> >> >>> ex:person1 ex:addressType "complexAddress".
> >> >>> I want to define two alternative shapes for addresses: one is
> >> >>> simple,
> >> >>> i.e. the literal value "Street xzy plz 12345 ...", and one is
> >> >>> complex,
> >> >>> i.e. an instance of ex:complexAddress.
> >> >>> How do I model the choice between the two address' shapes based on
> >> >>> the
> >> >>> values "simpleAddress" vs. "complexAddress"?
> >> >>> Regards,
> >> >>> Felix
> >> >> Links:
> >> >> ------
> >> >> [1]
> https://gist.github.com/simonstey/e3add7ff0740dd95a4c80d26840ca3e3
>
>
>

Received on Wednesday, 24 April 2019 05:35:48 UTC