- From: Felix Sasaki <felix@sasakiatcf.com>
- Date: Wed, 24 Apr 2019 07:35:07 +0200
- To: Irene Polikoff <irene@topquadrant.com>
- Cc: Håvard M. Ottestad <hmottestad@gmail.com>, Simon Steyskal <simon.steyskal@wu.ac.at>, public-shacl@w3.org
- Message-ID: <CAL58czopkf8VsEtfjLDbG4ga2CRyQruw4mnk-J31r8nS6E1KhA@mail.gmail.com>
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