Re: Question on value based constraints

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 Saturday, 20 April 2019 20:57:34 UTC