1

I'm trying to create nested mappings between XML and Turtle. I'm using the RMLMapper v4.9.0 for this purpose.

Here is a sample XML file that I would like to map:

<?xml version="1.0" encoding="utf-8"?>
<persons>
    <person>
        <name>JohnDoe</name>
        <address>
            <number>123</number>
            <street>Main</street>
            <city>Anytown</city>
        </address>
        <address>
            <number>1234</number>
            <street>Second</street>
            <city>Anytown</city>
        </address>
    </person>
    <person>
        <name>JaneDoe</name>
    </person>
</persons>

Here is the Turtle output that I would like to generate:

@prefix ex: <http://example.com/> .

<http://example.com/ns#JaneDoe> a ex:Person .

<http://example.com/ns#JohnDoe> a ex:Person;
    ex:has_address [
        a ex:Address ;
        ex:has_city "Anytown";
        ex:has_number "123";
        ex:has_street "Main" .
    ] ;
    ex:has_address [
        a ex:Address ;
        ex:has_city "Anytown";
        ex:has_number "1234";
        ex:has_street "Second" .
    ] ;
.  

How can I achieve this type of nesting/format?

I've achieved a somewhat similar output by creating the subjects of the address triples as rr:termType rr:BlankNode.
However, I would prefer the subject to not be repeated and the output of square brackets instead of BlankNodes.

@prefix ex: <http://example.com/> .

<http://example.com/ns#JaneDoe> a ex:Person .

<http://example.com/ns#JohnDoe> a ex:Person;
  ex:has_address _:0 .

_:0 a ex:Address;
  ex:has_city "Anytown";
  ex:has_number "123";
  ex:has_street "Main" .

<http://example.com/ns#JohnDoe> ex:has_address _:1 .

_:1 a ex:Address;
  ex:has_city "Anytown";
  ex:has_number "1234";
  ex:has_street "Second" .

I've used the following map:

@prefix rml: <http://semweb.mmlab.be/ns/rml#>.
@prefix ql: <http://semweb.mmlab.be/ns/ql#>.
@prefix rr: <http://www.w3.org/ns/r2rml#>.
@prefix ex: <http://example.com/> .
@base <http://example.com/ns#> .


_:personMap a rr:TriplesMap ;

    # XML source file with xPath iterator
    rml:logicalSource [
        rml:source "example.xml" ;
        rml:referenceFormulation ql:XPath ;
        rml:iterator "//*[local-name()='person']"
    ] ;

    rr:subjectMap   [
                        rml:reference "name" ;
                        rr:class ex:Person ;
                    ] ;

    # address
    rr:predicateObjectMap   [   
                                rr:predicateMap [ rr:constant ex:has_address ] ;
                                rr:objectMap    [ 
                                                  rr:parentTriplesMap _:addressMap ;
                                                  rr:joinCondition [
                                                    rr:child "name" ;
                                                    rr:parent "ancestor::*/name" ;
                                                  ] ;
                                                ] ;
                            ] ;
    .


_:addressMap a rr:TriplesMap ;

    # XML source file with xPath iterator
    rml:logicalSource [
        rml:source "example.xml" ;
        rml:referenceFormulation ql:XPath ;
        rml:iterator "//*[local-name()='address']"
    ] ; 
    
    rr:subjectMap   [   
                        rr:termType rr:BlankNode ;
                        rr:class ex:Address
                    ] ;
    
    # city
    rr:predicateObjectMap   [   
                                rr:predicateMap [ rr:constant ex:has_city ] ;
                                rr:objectMap    [ rml:reference "city" ] ;
                            ] ;

    # street
    rr:predicateObjectMap   [   
                                rr:predicateMap [ rr:constant ex:has_street ] ;
                                rr:objectMap    [ rml:reference "street" ] ;
                            ] ;

    # number
    rr:predicateObjectMap   [   
                                rr:predicateMap [ rr:constant ex:has_number ] ;
                                rr:objectMap    [ rml:reference "number" ] ;
                            ] ;
    .
Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
  • 1
    your "problem" is just a matter of serialization as both documents are semantically equivalent. If your R2RML processor doesn't allow for more compact Turtle then you have to use some other API as post-processing. For example with Apache Jena RIOT you can do `riot --syntax=Turtle --formatted=Turtle YOUR_TURTLE_FILE_HERE.ttl` and it will print something like you want. Note, it can be memory consuming for larger files because you have to keep track triples before you can group by subject etc. – UninformedUser Oct 19 '20 at 10:08
  • The comment from @UninformedUser is correct (This should be turned into an answer). Both documents are semantically equivalent. – Dylan Van Assche Oct 26 '20 at 10:46

0 Answers0