RDFLib / rdflib-jsonld

JSON-LD parser and serializer plugins for RDFLib
Other
280 stars 71 forks source link

Serialization problem: Form dict to List? #19

Open fdelavega opened 10 years ago

fdelavega commented 10 years ago

Hi, I have updated the lib, and it has started to fail. When serializing to json-ld my code was specting a dict, but now it returns a list. tring the example of your documentation:

testrdf = '''
... @prefix dc:  .
... 
...     dc:title "Someone's Homepage"@en .
... ''

g = Graph().parse(data=testrdf, format='n3')

print(g.serialize(format='json-ld', indent=4))

It returns:

[
    {
        "@id": "http://example.org/about",
        "http://purl.org/dc/terms/title": [
            {
                "@language": "en",
                "@value": "Someone's Homepage"
            }
        ]
    }
]

and it should return:

{
    "@id": "http://example.org/about",
    "http://purl.org/dc/terms/title": [
        {
            "@language": "en",
            "@value": "Someone's Homepage"
        }
    ]
}

Note that it returns a list containing the spected result instead of the result itself. However, the second example (the example passing a new context) is correct, the serialization returns exactly the same as in your example.

Is this the expected behaviour?

fdelavega commented 10 years ago

I have already fixed this problem, the attribute to use the contex defined in the document has changed form "compact" to "auto_compact", so I can serialize correctly now; however, I have a different problem when parsing documents in json-ld. It generates an empty graph. Debugging the code of the file parser.py:

parser.py line 96:

if not isinstance(resources, list):
            resources = [resources]

In this case when tring to parse a json document that has been serialized with the option auto_compact set to True, the resources variable contains a dict with 2 fields, something like:

{
    @context: {
        ...
    },
   @graph: [
      ..
   ]
}

so after executing the line 97 resources does not contain a list containig the nodes of the graph. I have fixed it to my concrete use case just by changing the code to:

if not isinstance(resources, list):
            if '@graph' in resources:
                resources = resources['@graph']
            else:
                resources = [resources]
niklasl commented 10 years ago

Hi!

Picking out resources of a graph is done on line 174, so I'm unsure why it doesn't work in your case. Do you have an example of data which doesn't roundtrip properly? Perhaps what you have is a named graph (an object with both @id and @graph keys)?

(In general, the compaction, and parsing thereof, should behave according to the JSON-LD algorithms specification. It would be great if you'd compare what you're after with that, and/or by checking if the results differ from what the JSON-LD Playground produces.)

fdelavega commented 10 years ago

Hi,

An example of the problem, I have the file basic_usdl.ttl that contains:

@prefix foaf: <http://xmlns.com/foaf/0.1/> . 
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . 
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . 
@prefix msm: <http://cms-wg.sti2.org/ns/minimal-service-model#> . 
@prefix owl: <http://www.w3.org/2002/07/owl#> . 
@prefix dcterms: <http://purl.org/dc/terms/> . 
@prefix usdl: <http://www.linked-usdl.org/ns/usdl-core#> . 
@prefix legal: <http://www.linked-usdl.org/ns/usdl-legal#> . 
@prefix price: <http://www.linked-usdl.org/ns/usdl-pricing#> . 
@prefix sla: <http://www.linked-usdl.org/ns/usdl-sla#> . 
@prefix sec: <http://www.linked-usdl.org/ns/usdl-sec#> . 
@prefix blueprint: <http://bizweb.sap.com/TR/blueprint#> . 
@prefix vcard: <http://www.w3.org/2006/vcard/ns#> . 
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . 
@prefix ctag: <http://commontag.org/ns#> . 
@prefix org: <http://www.w3.org/ns/org#> . 
@prefix skos: <http://www.w3.org/2004/02/skos/core#> . 
@prefix time: <http://www.w3.org/2006/time#> . 
@prefix gr: <http://purl.org/goodrelations/v1#> . 
@prefix doap: <http://usefulinc.com/ns/doap#> . 

<http://localhost:8000/usdleditor#3RDPhVqBqrUiClCDh> 
    a usdl:Service ; 
   dcterms:modified ""^^xsd:datetime ; 
   dcterms:created ""^^xsd:datetime ; 
   foaf:thumbnail <http://ddrsl001xb.drss.sap.corp:8888/bizwebportal/05_Icon_UIDivision.png> ; 
   foaf:depiction <http://ddrsl001xb.drss.sap.corp:8888/bizweb/icons/GBFlipper_AW.png> ; 
   dcterms:title "example service"@en ; 
   dcterms:abstract "Short description"@en ;
   usdl:versionInfo "1.0" ;
   dcterms:description "Long description"@en . 

<http://localhost:8000/usdleditor#1XhhFQvhxOhhb24RT> 
   a usdl:ServiceOffering ; 
   dcterms:description ""@en ; 
   usdl:validFrom "2011-12-01"^^xsd:datetime ; 
   usdl:validThrough "2011-12-31"^^xsd:datetime ; 
   usdl:includes <http://localhost:8000/usdleditor#3RDPhVqBqrUiClCDh> ; 
   dcterms:title "test offering"@en . 

Now i execute the following commands in ipython.

>>>import rdflib
>>>f = open("basic_usdl.ttl", "rb")
>>>g = rdflib.Graph().parse(data=f.read(), format='n3')
>>>print(g.serialize(format='json-ld', auto_compact=True, indent=4))

The print returns the following document:

{
    "@context": {
        "blueprint": "http://bizweb.sap.com/TR/blueprint#",
        "ctag": "http://commontag.org/ns#",
        "dcterms": "http://purl.org/dc/terms/",
        "doap": "http://usefulinc.com/ns/doap#",
        "foaf": "http://xmlns.com/foaf/0.1/",
        "gr": "http://purl.org/goodrelations/v1#",
        "legal": "http://www.linked-usdl.org/ns/usdl-legal#",
        "msm": "http://cms-wg.sti2.org/ns/minimal-service-model#",
        "org": "http://www.w3.org/ns/org#",
        "owl": "http://www.w3.org/2002/07/owl#",
        "price": "http://www.linked-usdl.org/ns/usdl-pricing#",
        "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
        "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
        "sec": "http://www.linked-usdl.org/ns/usdl-sec#",
        "skos": "http://www.w3.org/2004/02/skos/core#",
        "sla": "http://www.linked-usdl.org/ns/usdl-sla#",
        "time": "http://www.w3.org/2006/time#",
        "usdl": "http://www.linked-usdl.org/ns/usdl-core#",
        "vcard": "http://www.w3.org/2006/vcard/ns#",
        "xsd": "http://www.w3.org/2001/XMLSchema#"
    },
    "@graph": [
        {
            "@id": "http://localhost:8000/usdleditor#1XhhFQvhxOhhb24RT",
            "@type": "usdl:ServiceOffering",
            "dcterms:description": {
                "@language": "en",
                "@value": ""
            },
            "dcterms:title": {
                "@language": "en",
                "@value": "test offering"
            },
            "usdl:includes": {
                "@id": "http://localhost:8000/usdleditor#3RDPhVqBqrUiClCDh"
            },
            "usdl:validFrom": {
                "@type": "xsd:datetime",
                "@value": "2011-12-01"
            },
            "usdl:validThrough": {
                "@type": "xsd:datetime",
                "@value": "2011-12-31"
            }
        },
        {
            "@id": "http://localhost:8000/usdleditor#3RDPhVqBqrUiClCDh",
            "@type": "usdl:Service",
            "dcterms:abstract": {
                "@language": "en",
                "@value": "Short description"
            },
            "dcterms:created": {
                "@type": "xsd:datetime",
                "@value": ""
            },
            "dcterms:description": {
                "@language": "en",
                "@value": "Long description"
            },
            "dcterms:modified": {
                "@type": "xsd:datetime",
                "@value": ""
            },
            "dcterms:title": {
                "@language": "en",
                "@value": "example service"
            },
            "foaf:depiction": {
                "@id": "http://ddrsl001xb.drss.sap.corp:8888/bizweb/icons/GBFlipper_AW.png"
            },
            "foaf:thumbnail": {
                "@id": "http://ddrsl001xb.drss.sap.corp:8888/bizwebportal/05_Icon_UIDivision.png"
            },
            "usdl:versionInfo": "1.0"
        }
    ]
}

Now that I have seen the json document I store and parse it:

>>>json_ser = g.serialize(format='json-ld', auto_compact=True, indent=4)
>>>g1 = rdflib.Graph().parse(data=json_ser, format='json-ld')
>>>print(g1.serialize(format='json-ld', auto_compact=True, indent=4))

This print retunrs:

{
    "@context": {
        "blueprint": "http://bizweb.sap.com/TR/blueprint#",
        "ctag": "http://commontag.org/ns#",
        "dcterms": "http://purl.org/dc/terms/",
        "doap": "http://usefulinc.com/ns/doap#",
        "foaf": "http://xmlns.com/foaf/0.1/",
        "gr": "http://purl.org/goodrelations/v1#",
        "legal": "http://www.linked-usdl.org/ns/usdl-legal#",
        "msm": "http://cms-wg.sti2.org/ns/minimal-service-model#",
        "org": "http://www.w3.org/ns/org#",
        "owl": "http://www.w3.org/2002/07/owl#",
        "price": "http://www.linked-usdl.org/ns/usdl-pricing#",
        "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
        "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
        "sec": "http://www.linked-usdl.org/ns/usdl-sec#",
        "skos": "http://www.w3.org/2004/02/skos/core#",
        "sla": "http://www.linked-usdl.org/ns/usdl-sla#",
        "time": "http://www.w3.org/2006/time#",
        "usdl": "http://www.linked-usdl.org/ns/usdl-core#",
        "vcard": "http://www.w3.org/2006/vcard/ns#",
        "xsd": "http://www.w3.org/2001/XMLSchema#"
    },
    "@graph": []
}

This is not a problem with the serialization, I have checked that the graph has not any tuple. If it helps you to find the problem, note that it works with the modification I commented before.

niklasl commented 10 years ago

Ah, thanks, I can reproduce the problem now. It seems the serializer only works properly with ConjunctiveGraph instances (I did some changes in that area a while ago).

I will investigate. Meanwhile, you can make it work by changing your code to this:

json_ser = g.serialize(format='json-ld', auto_compact=True, indent=4)
g1 = rdflib.ConjunctiveGraph()
g1.parse(data=json_ser, format='json-ld')
print(g1.serialize(format='json-ld', auto_compact=True, indent=4))

(Note that the graph.parse method returns the resulting graph, so you need to do this in three steps.)