citiususc / jsonschema2shacl

A Python program that creates SHACL shapes from JSON Schema
Apache License 2.0
2 stars 1 forks source link

Object type property translation wrong #3

Closed xuemduan closed 4 months ago

xuemduan commented 4 months ago

The object type property is expected to be translated to a Property Shape first, then use sh:node to connect to another new node shape instead of directly creating a Node Shape for it.

For example, if we have a property

"P1": { 
    "type": "object", 
        "properties": { 
            "P2": { "type": "string" }, 
            "P3": { "type": "string" } } } } }

what we need to create is

PS1 a sh:PropertyShape ;
    sh:path :P1 ;
    sh:node NS1  .

NS1 a sh:NodeShape ;
    sh:property PS2 , PS3 .

PS2 a sh:PropertyShape ;
    sh:path :P2 .

PS3 a sh:PropertyShape ;
    sh:path :P3 .
dachafra commented 4 months ago

@xuemduan could you also add the example we have? it's easy to understand :-)

xuemduan commented 4 months ago

Sure, in terms of a real example, if we have

{ "type": "object", 
"name": "persona", 
"properties": { 
    "first_name": { "type": "string" }, 
    "address": { 
    "type": "object", 
        "properties": { 
            "street_address": { "type": "string" }, 
            "city": { "type": "string" } } } } }

the shape structure we need is

:NS/persona a sh:NodeShape ;
    sh:property :PS/first_name , :PS/address ;  
    sh:targetClass :persona .

:PS/address a sh:PropertyShape ;    sh:name "city" ;
    sh:path :address ; sh:node :NS/address

:NS/address a sh:NodeShape ;        sh:name "address" ;
    sh:property :PS/city,   :PS/street_address ;

:PS/first_name a sh:PropertyShape ;     sh:name "first_name" ;
    sh:path :first_name .

:PS/city a sh:PropertyShape ;       sh:name "city" ;
    sh:path :city .

:PS/street_address a sh:PropertyShape ;     sh:name "street_address" ;
    sh:path :street_address .
osm0512 commented 4 months ago

So, in the case where we create an object inside another object, first we create a Property Shape. In case this new child object, which is inside the parent object, has some properties, I create a NodeShape and link it to the Property Shape with sh:Node. Is this correct? @xuemduan

xuemduan commented 4 months ago

@osm0512 Yes, if you check your current implementation, you require the node from the first node shape to have two properties (city, street_address), but what expected is that the node should have a :address property first (e.g., in RDF we have :node :address blanknode), then the blanknode will have the two properties (city, street_address). Thus we need to have a property shape for :address first.

osm0512 commented 4 months ago

Ok I will fix it