RMLio / rmlmapper-java

The RMLMapper executes RML rules to generate high quality Linked Data from multiple originally (semi-)structured data sources
http://rml.io
MIT License
147 stars 61 forks source link

detecting if a JSON dictonary key is there and if so write out an IRI #99

Closed CyberDaedalus00 closed 3 years ago

CyberDaedalus00 commented 3 years ago

Is there a way to detect if a key in a JSON dictionary exists and if so, write out a specific IRI for the value of the predicate? { "type": "file", "spec_version": "2.1", "id": "file--9a1f834d-2506-5367-baec-7aa63996ac43", "name": "foo.zip", "size": 25536, "hashes": { "SHA-256": "35a01331e9ad96f751278b891b6ea09699806faedfa237d40513d92ad1b7100f" }, "mime_type": "application/zip", "extensions": { "archive-ext": { "comment": "archive of files", "contains_refs": [ "file--019fde1c-94ca-5967-8b3c-a906a51d87ac", "file--94fc2163-dec3-5715-b824-6e689c4de865", "file--d07ff290-d7e0-545b-a2ff-04602a9e0b73" ] }, "ntfs-ext": { "sid": "S-1-5-21-7375663-6890924511-1272660413-2944159", "alternate_data_streams": [ { "name": "second.stream", "size": 25536 } ] } }

Using the JSON example above, I've come up with a means to detect if a specific key value is in the dictionary. But I can seem to find the right predicate mapping to cause a well known IRI to be written out. Instead, I either get the value of the dictionary key or I get an error: Not a valid (absolute) IRI: {comment=archive of files, contains_refs=["file--019fde1c-94ca-5967-8b3c-a906a51d87ac","file--94fc2163-dec3-5715-b824-6e689c4de865","file--d07ff290-d7e0-545b-a2ff-04602a9e0b73"]}

When I try the following predicate mapping:

archive-ext Legacy Extension

rr:predicateObjectMap [
    rr:predicate cti:extensions ;
    rr:objectMap [
        rml:reference "extensions.archive-ext" ;
        rr:constant <http://cti.oasis-open.org/extension-definition--b4fc6cdc-5af9-5736-97b7-256f8552c7e1> ;
        rr:termType rr:IRI ;
    ]
] ;

I get the following error: Not a valid (absolute) IRI: {comment=archive of files, contains_refs=["file--019fde1c-94ca-5967-8b3c-a906a51d87ac","file--94fc2163-dec3-5715-b824-6e689c4de865","file--d07ff290-d7e0-545b-a2ff-04602a9e0b73"]}

If I change the predicate mapping to make the value of the constant a string, as follows:

# archive-ext Legacy Extension
rr:predicateObjectMap [
    rr:predicate cti:extensions ;
    rr:objectMap [
        rml:reference "extensions.archive-ext" ;
        # rr:object http://cti.oasis-open.org/extension-definition--b4fc6cdc-5af9-5736-97b7-256f8552c7e1 ;
        rr:constant "<http://cti.oasis-open.org/extension-definition--b4fc6cdc-5af9-5736-97b7-256f8552c7e1>" ;
        # rr:termType rr:IRI ;
    ]
] ;

I don't get an error, but instead the value of the predicate is the body of the dictionary entry associated with the key as you can see below:

http://cti.oasis-open.org/file--9a1f834d-2506-5367-baec-7aa63996ac43 a stix:File; cti:extensions "{comment=archive of files, contains_refs=[\"file--019fde1c-94ca-5967-8b3c-a906a51d87ac\",\"file--94fc2163-dec3-5715-b824-6e689c4de865\",\"file--d07ff290-d7e0-545b-a2ff-04602a9e0b73\"]}"; cti:hashes http://cti.oasis-open.org/hashes--9cd6855d-125e-4725-be56-3b0a279524b6; cti:id "file--9a1f834d-2506-5367-baec-7aa63996ac43"; cti:mime_type "application/zip";

I did try to use rr:object in place of rr:constant, but that produce the same output as above.

Any suggestions?

thomas-delva commented 3 years ago

Hi and thank you for using RML,

Conditional mappings can be done using RML together with FnO functions.

You can find documentation for RML+FnO here.

I created a mapping file which handles your specific example in the more concise YARRRML syntax for RML (specification, playground):

prefixes:
  ex: "http://example.com/"
  idlab-fn: "http://example.com/idlab/function/"

mappings:
  person:
    sources:
      - ['persons.json~jsonpath', '$']
    s: http://example.com/person/$(type)
    po:
      - p: ex:predicate
        o:
          - function: idlab-fn:trueCondition
            parameters:
              - parameter: idlab-fn:strBoolean
                value: 
                  function: idlab-fn:listContainsElement
                  parameters:
                    - [idlab-fn:list, $(extensions.archive-ext.contains_refs)]
                    - [idlab-fn:str, file--019fde1c-94ca-5967-8b3c-a906a51d87ac]
              - [idlab-fn:str, ex:object]

This creates a triple like ex:file ex:predicate ex:object when the value of parameter idlab-fn:str is contained in the list returned by the JSONPath expression extensions.archive-ext.contains_refs.