diff --git a/.gitignore b/.gitignore index ea29b39..a820245 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ venv *__pycache__ test-cases/burp.jar +**/node_modules/ \ No newline at end of file diff --git a/shapes/lv.ttl b/shapes/lv.ttl index 6431da2..1d1e9fe 100644 --- a/shapes/lv.ttl +++ b/shapes/lv.ttl @@ -240,15 +240,32 @@ rmlsh:LogicalViewJoinShape a sh:NodeShape ; A field of the logical view join. """ ; sh:message """ - At least one rml:field property must be specified for a rml:LogicalViewJoin, with a resource as its value. + At least one rml:field property must be specified for a rml:LogicalViewJoin, with a leaf expression field as its value. """ ; sh:path rml:field ; sh:minCount 1 ; sh:nodeKind sh:BlankNodeOrIRI ; - sh:or ( - [ sh:node rmlsh:ExpressionFieldShape ] - [ sh:node rmlsh:IterableFieldShape ] - ) + sh:node rmlsh:LeafExpressionFieldShape ; + ] . + +rmlsh:LeafExpressionFieldShape a sh:NodeShape ; + rdfs:label "Leaf Expression Field" ; + rdfs:comment """ + A leaf expression field is an expression field without nested fields. + """ ; + sh:message """ + Node must have a valid rml:ExpressionField description. + """ ; + sh:node rmlsh:ExpressionFieldShape ; + sh:property [ + sh:description """ + A leaf expression field is an expression field without nested fields. + """ ; + sh:message """ + A leaf expression field has no nested fields. + """ ; + sh:path rml:field ; + sh:maxCount 0 ; ] . rmlsh:StructuralAnnotationShape a sh:NodeShape; @@ -312,3 +329,33 @@ rmlsh:InclusionAnnotationShape a sh:NodeShape; sh:maxCount 1 ; sh:nodeKind sh:BlankNodeOrIRI ; ] . + +rmlsh:parentCyclesShape a sh:NodeShape ; + sh:targetSubjectsOf rml:viewOn ; + sh:targetSubjectsOf rml:field ; + sh:sparql [ + a sh:SPARQLConstraint ; + sh:message "There must be no cycles via rml:viewOn or rml:Field." ; + sh:select """ + PREFIX rml: + SELECT ?this + WHERE { + ?this (rml:viewOn|rml:field)+ ?this . + } + """ ; + ] . + +rmlsh:joinCyclesShape a sh:NodeShape ; + sh:targetSubjectsOf rml:viewOn ; + sh:sparql [ + a sh:SPARQLConstraint ; + sh:message "There must be no cycles via rml:viewOn and rml:leftJoin or rml:innerJoin." ; + sh:select """ + PREFIX rml: + SELECT ?this + WHERE { + ?this a rml:LogicalView . + ?this ((rml:leftJoin|rml:innerJoin)/rml:parentLogicalView)+ ?this . + } + """ ; + ] . diff --git a/shapes/tests.py b/shapes/tests.py index 8fe1fdd..295eca0 100755 --- a/shapes/tests.py +++ b/shapes/tests.py @@ -53,7 +53,12 @@ def test_validation_rules(self, path: str) -> None: rules test cases. """ print(f'Testing validation with: {path}') - self._validate_rules(path) + if 'RMLLVTC0008a' in path or 'RMLLVTC0008b' in path or \ + 'RMLLVTC0008c' in path or 'RMLLVTC0008d' in path: + with self.assertRaises(Exception): + self._validate_rules(path) + else: + self._validate_rules(path) if __name__ == '__main__': diff --git a/spec/config.js b/spec/config.js index c582e09..a95a859 100644 --- a/spec/config.js +++ b/spec/config.js @@ -33,7 +33,7 @@ var respecConfig = { // formal title, define it here // subtitle : "White Paper", // if you wish the publication date to be other than the last modification, set this - publishDate: "2025-10-23", + publishDate: "2025-11-20", // if the specification's copyright date is a range of years, specify // the start date here: copyrightStart: "2024", diff --git a/spec/docs/20251120/index.html b/spec/docs/20251120/index.html new file mode 100644 index 0000000..822710b --- /dev/null +++ b/spec/docs/20251120/index.html @@ -0,0 +1,2849 @@ + + + + + + + + +RML Logical Views + + + + + + + + + + + + + + + + + + + + + +
+ +

RML Logical Views

+

+ Draft Community Group Report + +

+
+ +
Latest published version:
+ https://w3id.org/rml/lv/spec/ +
+
Latest editor's draft:
https://w3id.org/rml/lv/spec
+ + + + +
Editors:
+ (Skemu) +
+ (Ghent University – imec – IDLab) +
+ +
Authors:
+ (Skemu) +
+ (Ghent University – imec – IDLab) +
+ (Free University of Bozen-Bolzano) +
+ +
This Version
+ https://kg-construct.github.io/rml-lv/spec/docs/20251120/ +
Previous Version
+ https://kg-construct.github.io/rml-lv/spec/docs/20250924/ +
Website
+ https://github.com/kg-construct/rml-lv/ +
+
+ + +
+
+

Abstract

RML logical views is an extension of the RDF Mapping Language (RML) that increases the language's capability to +construct RDF datasets from nested input data, to join data sources (also across data hierarchies), +and to handle data sources that mix source formats, +by allowing to specify a logical view: a flattened, source format-agnostic view +over one or more existing data sources. +Additionally, it provides a mechanism to express relationships between data sources, +as well as additional information about their fields, through structural annotations.

+

This document describes RML logical views through definitions and examples.

+

The version of this document is DRAFT.

+
+ +

Status of This Document

+ This specification was published by the + Knowledge Graph Construction Community Group. It is not a W3C Standard nor is it + on the W3C Standards Track. + + Please note that under the + W3C Community Contributor License Agreement (CLA) + there is a limited opt-out and other conditions apply. + + Learn more about + W3C Community and Business Groups. +

+

This is an early draft, +yet efforts are made to keep things stable.

+

+
+ +

1. Overview

This section is non-normative.

+

1.1 Document conventions

We assume readers have basic familiarity with RDF and RML concepts.

+

In this document, examples assume +the following namespace prefix bindings unless otherwise stated:

+ + + + + + + + + + + + + + + + + + + +
PrefixNamespace
rml:http://w3id.org/rml/
xsd:http://www.w3.org/2001/XMLSchema#
:http://example.org/
+

The examples are contained in color-coded boxes. We use the Turtle syntax [turtle] to write RDF.

+ + + + + + +

1.2 Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

+ The key words MAY and MUST in this document + are to be interpreted as described in + BCP 14 + [RFC2119] [RFC8174] + when, and only when, they appear in all + capitals, as shown here. +

+ +
+ +

2. Problem

This section is non-normative.

+

RML Logical Views aims to resolve challenges such as handling hierarchy of nested data, more flexible joining (also across data hierarchies), and handling data sources that mix source formats.

+

2.1 Nested data structures

+

References to nested data structures, like JSON or XML, may return multiple values. These values can be composite: they may again contain multiple values. +[RML-Core] defines mapping constructs that produce results by combining the results of other mapping constructs in a specific order. +For example, a triples map combines the results of a subject map and a predicate-object map in that order. +Another example is a template expression, +which combines character strings and zero or more reference expressions in declared order. +When mapping constructs produce multiple results, the combining mapping constructs will apply an n-ary Cartesian product over the sets of results, maintaining the order of the mapping constructs. In the case of nested data structures, this may cause the generation of results that do not match the source hierarchy, i.e. do not follow the root-to-leaf paths in the source data, since values are combined irrespective of it.

+

Furthermore, there is varying expressiveness in data source expression and query languages, and many languages have limited support for hierarchy traversal. For example, JSONPath has no operator to refer to an ancestor in the document hierarchy [RFC9535].

+

This limits the ability of RML-Core to map nested data.

+ + + +

2.2 Mixed data formats

+

Data in one format can contain multiple or composite values stored in another format, e.g. a CSV dataset could contain columns containing JSON values. To define the expected form of references to input data RML-Core employs the notion of a reference formulation. A logical source is limited to having a single reference formulation, meaning mixed format data can only be referenced using a query language that supports just one of the formats.

+ + +

2.3 Joining of data sources

+

RML-Core restricts join operations to referencing object maps. Since a referencing object map can only generate an object that is an IRI or blank node subject as specified by a parent triples map, it is not possible to combine data from two sources in one term, use data from a join on another position than the object, or generate a literal using data from a join. +Moreover, RML-Core cannot declare join operations correctly across hierarchies.

+
+ +

3. Logical views

A logical view is a type of abstract logical source that is derived from another abstract logical source by defining fields with data from said abstract logical source.

+

A logical view (rml:LogicalView) is represented by a resource that MUST contain:

+
    +
  • exactly one view on property (rml:viewOn), whose value is a abstract logical source (rml:AbstractLogicalSource),
  • +
  • at least one field property (rml:field), whose value is a field (rml:Field).
  • +
  • zero or more join properties (rml:leftJoin, rml:innerJoin), whose value is a logical view join (rml:LogicalViewJoin).
  • +
+

A logical view (rml:LogicalView) has an implicit default reference formulation (rml:referenceFormulation) and logical iterator (rml:iterator), which MUST not be overwritten.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDomainRange
rml:viewOnrml:LogicalViewrml:AbstractLogicalSource
rml:fieldrml:LogicalView or rml:Fieldrml:Field
rml:leftJoinrml:LogicalViewrml:LogicalViewJoin
rml:innerJoinrml:LogicalViewrml:LogicalViewJoin
+

3.1 Logical view iterator

The logical iterator of a logical view produces a logical view iteration sequence, i.e. an ordered sequence of sets of key-value pairs. +Each set of key-value pairs represents a logical iteration of the logical view, called a logical view iteration.

+

Each key in a logical view iteration sequence is a string and each value is a record or a non-negative integer. +A record is either an iterable record or an expression record.

+

An iterable record is a logical iteration, i.e. an item on which expressions can be evaluated.

+

An expression record is one element of an expression evaluation result.

+

A record key has a record as value. +Each record key is accompanied with an index key.

+

An index key has a non-negative integer as value, indicating the zero-based position of the corresponding record.

+ +
Note
+ +

A logical view iteration sequence MUST have a finite set of keys that appear in each logical view iteration. +In any particular logical view iteration, the value of a key MAY be a null value.

+

Each logical view iteration has at least the following keys:

+ +

Additional keys-value pairs with custom record keys can be defined by the fields of the logical view, +which is further detailed in 4. Fields.

+

3.2 Logical view expressions

A logical view reference is a reference expression that references a defined referenceable key in a logical view iteration. +A referenceable key is either

+ +

A record key of an iterable record (including the record key <it>) cannot be referenced.

+

The expression evaluation result of a logical view reference is the value corresponding to the referenced key.

+

The natural RDF datatype of an index key's values is xsd:integer. +The natural RDF datatype of an expression record is obtained by applying the natural mapping of the reference formulation used to retrieve the record.

+

A logical view reference can be used in expression maps just as any other reference expression.

+

When a non-existing or a non-referenceable key is referenced, RML processors should report an error.

+
+ +

4. Fields

A field gives a name to data derived from the abstract logical source on which the logical view is defined.

+

A field (rml:Field) is represented by a resource that MUST contain:

+
    +
  • exactly one field name property (rml:fieldName), that specifies the declared name of the field
  • +
  • zero or more field properties (rml:field), to describe nested field, also of the type rml:Field
  • +
+ + + + + + + + + + + + + + + + + + +
PropertyDomainRange
rml:fieldNamerml:Fieldxsd:string
rml:fieldrml:LogicalView or rml:Fieldrml:Field
+

There are two types of fields: an expression field and an iterable field.

+

An expression field (rml:ExpressionField) is a type of expression map. +Consequently, an expression field MUST have an expression.

+

An iterable field (rml:IterableField) is a type of iterable. +Consequently, an iterable field MUST have a reference formulation and a logical iterator. +If no reference formulation is declared for an iterable field, the reference formulation of the field's parent is implied.

+

4.1 Field parents

A field MUST have a parent that is either the abstract logical source of the logical view or another field. The parent relation MUST not contain cycles: it is tree-shaped with a logical view as its root. The transitive parents of a field, i.e., the field's parent, the parent of the field's parent, etcetera, are fittingly called the field's ancestors. +A field's parent records are the records defined by the field's parent.

+

4.2 Field names

A field MUST have a declared name that is an alphanumerical string. Fields with the same parent MUST have different declared names. +We distinguish between the field's declared name and the field's absolute name. +If a field's parent is another field, the field's absolute name is the concatenation of the name of the parent field, a dot ., and the field's declared name. +Otherwise, the field's absolute name equals its declared name.

+ + +

4.3 Field records

A field defines records:

+ +

A field adds following keys and corresponding values to the logical view iteration sequence:

+ + + +

4.4 Field reference formulations

For the evaluation of the expression of an expression field (rml:ExpressionField) on the records of the field's parent, the parent's reference formulation is used. +Consequently, the parent of an expression field MUST be an iterable, i.e. an abstract logical source or iterable field.

+

The default reference formulation of an iterable field (rml:IterableField) is the reference formulation of the field's parent. +If the iterable field's parent is an expression field, a reference formulation MUST be declared for the iterable field. +Declaring a new reference formulation, i.e. a reference formulation that is different from the reference formulation of the field's parent, is only allowed when the field's parent is an expression field.

+ + +Note some columns in the table below have been shortened for brevity. +
+ +

5. Logical view joins

A logical view join (rml:LogicalViewJoin) is an operation that extends the logical iteration of one logical view (the child logical view) with fields derived from another logical view (the parent logical view), +using a join condition.

+

A logical view join MUST contain:

+
    +
  • exactly one parent logical view property (rml:parentLogicalView), whose value is a logical view (rml:LogicalView) that supplies the additional fields. This is referred to as the parent logical view.
  • +
  • at least one join condition property (rml:joinCondition), whose value is a join condition.
  • +
  • at least one field property (rml:field), whose value is a leaf expression field, i.e., an expression field (rml:ExpressionField) without nested fields. +This field MUST contain only logical view references that can be evaluated on the parent logical view. +The declared name of this field MUST be different from the absolute name of every other field in the child logical view.
  • +
+

Similar to how joins are defined in RML-Core, +the logical view in the subject position of the join property fulfills the role of child logical source in the join condition(s), but of the logical view join, and is referred to as child logical view. +The parent logical view fulfills the role of the parent logical source in the join condition(s), but of the logical view join.

+ + + + + + + + + + + + + + + + + + + + + + + +
PropertyDomainRange
rml:parentLogicalViewrml:LogicalViewJoinrml:LogicalView
rml:joinConditionrml:LogicalViewJoinrml:Join
rml:fieldrml:LogicalViewJoinrml:ExpressionField
+

5.1 Join types

The join property specifies the join type of the logical view join, i.e. a left join or an inner join.

+

A left join (rml:leftJoin) is the equivalent of a left (outer) join in SQL, where the child logical view is the left part of the join, and the parent logical view is the right part of the join. If any of the join conditions evaluates to false, the fields from the logical view join in the extended logical iteration contain a null value.

+

An inner join (rml:innerJoin) is the equivalent of an inner join in SQL. If any of the join conditions evaluates to false, the logical iteration is removed from the child logical view.

+

5.2 Logical view join examples

+

5.2.1 Left join

+ + +

5.2.2 Inner join

+ + + +

5.2.3 Two left joins

+
+ +

6. Structural Annotations

Structural annotations provide a mechanism to express relationships between logical views, as well as additional information about fields.

+

Each logical view MAY have zero or more structural annotation properties (rml:structuralAnnotation), connecting the logical view to a structural annotation object (i.e., of type rml:StructuralAnnotation).

+ + + + + + + + + + + + + +
PropertyDomainRange
rml:structuralAnnotationrml:LogicalViewrml:StructuralAnnotation
+

Following structural annotations MAY be defined:

+ +

All structural annotations of a logical view lv MUST have an on fields property (rml:onFields), linking the structural annotation to a list of field names occurring in lv. Intuitively, property on fields specifies the fields in lv that are involved by the structural annotation. The semantics of this involvement depends on the specific annotation.

+ + + + + + + + + + + + + +
PropertyDomainRange
rml:onFieldsrml:StructuralAnnotationrdf:List
+

6.1 Invariance Principle

+

Structural annotations provide additional information about the data that might be used by the RML processor to optimize the KG construction process. If this additional information is incorrect, then the RML processor might either fail or produce wrong results. When using structural annotations, users should make sure that the following invariance principle is satisfied:

+

For any source instances, the RDF graph produced by the RML engine using an RML mapping with annotations, and the same RML mapping where annotations have been removed, MUST be the same.

+

We emphasize that RML engines might exploit structural annotations, as they could totally ignore them. It is responsibility of the user to make sure that the annotations provided are indeed correct (that is, the data complies with the annotations). Sanity checks MAY be provided by the RML engines themselves, but this is not mandatory. Note that providing wrong annotations to an engine that takes annotations into account, for instance for applying optimizations, could result in a violation of the invariance principle, with unpredictable results.

+

6.2 IriSafe

+

An IriSafe structural annotation (rml:IriSafeAnnotation) on fields F indicates that the content of each field in F is IRI safe, that is, each field in F does not contain any character that is not in the iunreserved production in RFC3987.

+

6.3 PrimaryKey

+

A PrimaryKey structural annotation (rml:PrimaryKeyAnnotation) on fields (f1, ..., fn) imposes two conditions:

+
    +
  • no duplicate record sequences are present over the list of fields (f1, ..., fn);
  • +
  • No NULL value is admitted in any of the field f1, ..., fn.
  • +
+

Each logical view MAY specify AT MOST ONE PrimaryKey annotation.

+ + +

6.4 Unique

+

The Unique structural annotation (rml:UniqueAnnotation) is analogous to the notion of UNIQUE constraints in databases. Specifically, a Unique annotation on fields (f1, ..., fn) imposes the following condition:

+
    +
  • no duplicate record sequences are present over the list of fields (f1, ..., fn).
  • +
+

Note that every PrimaryKey annotation is, as a matter of fact, also a Unique annotation.

+

6.5 NotNull

+

The NotNull structural annotation (rml:NotNullAnnotation) is analogous to the notion of NOT NULL constraints in databases. Specifically, a NotNull annotation on fields F imposes that each field in F does not contain NULL values.

+
Note
+ +

6.6 ForeignKey

+

The ForeignKey structural annotation (rml:ForeignKeyAnnotation) is analogous to the notion of foreign key constraint in databases. Specifically, a ForeignKey annotation on fields (f1, ..., fn) , target view lv, and target fields (tf1,...,tfn) imposes the following conditions:

+
    +
  • each NULL-free record sequence over the list of fields (f1, ..., fn) occurs also as a record sequence in (tf1,...,tfn);
  • +
  • Target view lv defines a Unique annotation on fields (tf1,...,tfn).
  • +
+

The target view is a logical view specified through the property rml:targetView, whereas the target fields are an RDF list of field names specified through the property rml:targetFields. These two properties are specified as follows:

+ + + + + + + + + + + + + + + + + + +
PropertyDomainRange
rml:targetViewrml:InclusionAnnotationrml:LogicalView
rml:targetFieldsrml:InclusionAnnotationrdf:List
+

Therefore, each ForeignKey annotation MUST specify (additionally to the inherited rml:onFields property):

+
    +
  • Exactly one rml:targetView property
  • +
  • Exactly one rml:targetFields property.
  • +
+ + +

6.7 Inclusion

+

The Inclusion structural annotation (rml:InclusionAnnotation) is analogous to the notion of inclusion dependency in databases. Specifically, an Inclusion annotation on fields (f1, ..., fn) , target view lv, and target fields (tf1,...,tfn) imposes the following condition:

+
    +
  • each NULL-free record sequence over the list of fields (f1, ..., fn) occurs also as a record sequence in (tf1,...,tfn);
  • +
+

As for ForeignKey annotation, the target view MUST be a logical view specified through the property rml:targetView, whereas the target fields MUST be an RDF list of field names specified through the property rml:targetFields.

+

Therefore, each inclusion annotation MUST specify (additionally to the inherited rml:onFields property):

+
    +
  • Exactly one rml:targetView property
  • +
  • Exactly one rml:targetFields property.
  • +
+
Note
+ + + +

A. References

A.1 Normative references

+ +
[RFC2119]
+ Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119 +
[RFC8174]
+ Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174 +
[RFC9535]
+ JSONPath: Query Expressions for JSON. S. Gössner, Ed.; G. Normington, Ed.; C. Bormann, Ed. IETF. February 2024. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc9535 +
[RML-Core]
+ RML-Core. W3C. 16 February 2024. Draft Community Group Report. URL: https://w3id.org/rml/core/spec +
[RML-IO]
+ RML-IO. W3C. 27 September 2023. Draft Community Group Report. URL: https://w3id.org/rml/io/spec +
[turtle]
+ RDF 1.1 Turtle. Eric Prud'hommeaux; Gavin Carothers. W3C. 25 February 2014. W3C Recommendation. URL: https://www.w3.org/TR/turtle/ +
+
\ No newline at end of file diff --git a/spec/docs/20251120/resources/css/extras.css b/spec/docs/20251120/resources/css/extras.css new file mode 100644 index 0000000..3d7ce4e --- /dev/null +++ b/spec/docs/20251120/resources/css/extras.css @@ -0,0 +1,21 @@ + +a.sec-ref:before { + content: "“"; +} + +a.sec-ref:after { + content: "”"; +} + +span.orcid a { + text-decoration: none !important; + border: none !important; +} + +span.orcid a img { + transform: translateY(3px); +} + +html { + background: white !important; +} \ No newline at end of file diff --git a/spec/docs/20251120/resources/images/orcid_logo.png b/spec/docs/20251120/resources/images/orcid_logo.png new file mode 100644 index 0000000..e743726 Binary files /dev/null and b/spec/docs/20251120/resources/images/orcid_logo.png differ diff --git a/spec/docs/index.html b/spec/docs/index.html index 2765d22..50889e7 100644 --- a/spec/docs/index.html +++ b/spec/docs/index.html @@ -46,7 +46,7 @@ RML Logical Views - + + +RML-LV: Test Cases + + + + + + + + + + + + + + + +
+ +

RML-LV: Test Cases

+

+ Draft Community Group Report + +

+
+ +
Latest published version:
+ https://www.w3.org/RML-LV-Testcases/ +
+
Latest editor's draft:
https://w3id.org/rml/lv/test-cases/
+ + + + +
Editors:
+ (Skemu) +
+ (Ghent University – imec – IDLab) +
+ +
Authors:
+ (Skemu) +
+ (Ghent University – imec – IDLab) +
+
Feedback:
+ GitHub kg-construct/rml-lv + (pull requests, + new issue, + open issues) +
+ +
+ + +
+
+ + + +

Abstract

This document defines the RML-LV test cases to the determine the RML-LV specification conformance of tools.

+
+ +

Status of This Document

+ This specification was published by the + Knowledge Graph Construction Community Group. It is not a W3C Standard nor is it + on the W3C Standards Track. + + Please note that under the + W3C Community Contributor License Agreement (CLA) + there is a limited opt-out and other conditions apply. + + Learn more about + W3C Community and Business Groups. +

+ GitHub Issues are preferred for + discussion of this specification. + + +

+ +

1. Introduction

+

This document defines the RML-LV test cases, consisting of a collection of test case documents (input and expected output). +The purpose of the test cases is to determine the conformance of tools that execute RML rules to the RML-LV specification.

+
+ +

2. Data model

+

The test cases are semantically described for re-usability and shareability following the W3C Test case description. +Each test:Testcase as the following properties:

+
    +
  • dcterms:identifier: unique ID of the test case.
  • +
  • rmltest:hasError: if an error of the RML Processor is expected or not.
  • +
  • rmltest:input: One or more input data of the test case.
  • +
  • rmltest:output: One or more output data of the test case.
  • +
  • rmltest:inputFormat: the input data format.
  • +
  • rmltest:outputFormat: the output data format.
  • +
  • rmltest:mappingDocument: the RML mapping rules in Turtle.
  • +
+
+ +

3. Test cases

+

This section describes the RML-LV test cases. These descriptions are also available as RDF. +The files are available on GitHub in the folder test-cases. +Each test case is contained in a single folder, containing three types of files:

+
    +
  • Zero or more files containing the data sources, in the case of JSON, XML, CSV, or containing the SQL statements to create the necessary tables, in the case of MySQL, PostgreSQL, and SQL Server.
  • +
  • One file with the RML rules, called mapping.ttl, in the Turtle format.
  • +
  • Zero or more files with the expected RDF. No file is provided if an error is expected that must halt the generation of the RDF because of an error.
  • +
+
+ + +

4. RMLLVTC0000a

+

Title: Logical view on JSON source

+

Description: Test a view on a hierarchical source

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasName ;
+    rml:objectMap [
+      rml:reference "name" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasName> "alice" .
+<http://example.org/person/bob> <http://example.org/hasName> "bob" .
+
+
+

5. RMLLVTC0000b

+

Title: Logical view on CSV source

+

Description: Test a view on a tabular source

+

Error expected? No

+

Input

+
name,birthyear
+alice,1995
+bob,1999
+tobias,2005
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:csvSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:csvView a rml:LogicalView ;
+  rml:viewOn :csvSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "name" ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :csvView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasName ;
+    rml:objectMap [
+      rml:reference "name" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasName> "alice" .
+<http://example.org/person/bob> <http://example.org/hasName> "bob" .
+<http://example.org/person/tobias> <http://example.org/hasName> "tobias" .
+
+
+

6. RMLLVTC0000c

+

Title: Logical View on Logical View

+

Description: Test a view on a logical view

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] .
+
+:jsonViewOnJsonView a rml:LogicalView ;
+  rml:viewOn :jsonView ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "newName" ;
+    rml:reference "name" ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonViewOnJsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{newName}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasName ;
+    rml:objectMap [
+      rml:reference "newName" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasName> "alice" .
+<http://example.org/person/bob> <http://example.org/hasName> "bob" .
+
+
+

7. RMLLVTC0001a

+

Title: Expression Field: Reference

+

Description: Test a reference in an expression field

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasName ;
+    rml:objectMap [
+      rml:reference "name" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasName> "alice" .
+<http://example.org/person/bob> <http://example.org/hasName> "bob" .
+
+
+

8. RMLLVTC0001b

+

Title: Expression Field: Template

+

Description: Test a template in an expression field

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "race" ;
+    rml:constant "human" ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasRace ;
+    rml:objectMap [
+      rml:reference "race" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasRace> "human" .
+<http://example.org/person/bob> <http://example.org/hasRace> "human" .
+
+
+

9. RMLLVTC0001c

+

Title: Expression Field: Constant

+

Description: Test a constant expression in an expression field

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "lastName": "smith",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "lastName": "jones",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "fullName" ;
+    rml:template "{name} {lastName}" ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasFullName ;
+    rml:objectMap [
+      rml:reference "fullName" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasFullName> "alice smith" .
+<http://example.org/person/bob> <http://example.org/hasFullName> "bob jones" .
+
+
+

10. RMLLVTC0001d

+

Title: Expression Field Siblings

+

Description: Test multiple expression fields with the same parent

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "lastName": "smith",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "lastName": "jones",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "lastName" ;
+    rml:reference "$.lastName" ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasFullName ;
+    rml:objectMap [
+      rml:template "{name} {lastName}" ;
+      rml:termType rml:Literal ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasFullName> "alice smith" .
+<http://example.org/person/bob> <http://example.org/hasFullName> "bob jones" .
+
+
+

11. RMLLVTC0002a

+

Title: Iterable Field

+

Description: Test a nested field construction: iterable field with expression field as child

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:IterableField ;
+    rml:fieldName "item" ;
+    rml:iterator "$.items[*]" ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "type" ;
+      rml:reference "$.type" ;
+    ] ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasItem ;
+    rml:objectMap [
+      rml:template "http://example.org/person/{name}/item/{item.type}" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasItem> <http://example.org/person/alice/item/sword> .
+<http://example.org/person/alice> <http://example.org/hasItem> <http://example.org/person/alice/item/shield> .
+<http://example.org/person/bob> <http://example.org/hasItem> <http://example.org/person/bob/item/flower> .
+
+
+

12. RMLLVTC0002b

+

Title: Iterable Field with Multiple Children

+

Description: Test a nested field construction: iterable field with mulitple expression fields as children

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:IterableField ;
+    rml:fieldName "item" ;
+    rml:iterator "$.items[*]" ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "type" ;
+      rml:reference "$.type" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "weight" ;
+      rml:reference "$.weight" ;
+    ] ;
+  ] .
+
+:triplesMapItem a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}/item/{item.type}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasName ;
+    rml:objectMap [
+      rml:reference "item.type" ;
+    ] ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasWeight ;
+    rml:objectMap [
+      rml:reference "item.weight" ;
+      rml:datatype xsd:integer ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice/item/sword> <http://example.org/hasName> "sword" .
+<http://example.org/person/alice/item/sword> <http://example.org/hasWeight> "1500"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/person/alice/item/shield> <http://example.org/hasName> "shield" .
+<http://example.org/person/alice/item/shield> <http://example.org/hasWeight> "2500"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/person/bob/item/flower> <http://example.org/hasName> "flower" .
+<http://example.org/person/bob/item/flower> <http://example.org/hasWeight> "15"^^<http://www.w3.org/2001/XMLSchema#integer> .
+
+
+

13. RMLLVTC0002c

+

Title: Nested Iterable Fields

+

Description: Test a nested field construction: iterable field with an iterable field as child

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "measures": {
+            "weight": 1500,
+            "length": 30
+          }
+        },
+        {
+          "type": "shield",
+          "measures": {
+            "weight": 2500
+          }
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "measures" : {
+            "weight": 15,
+            "length" : 15
+          }
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:IterableField ;
+    rml:fieldName "item" ;
+    rml:iterator "$.items[*]" ;
+    rml:field [
+      rml:fieldName "type" ;
+      rml:reference "$.type" ;
+    ] ;
+    rml:field [
+      a rml:IterableField ;
+      rml:fieldName "measures";
+      rml:iterator "$.measures";
+      rml:field [
+        a rml:ExpressionField ;
+        rml:fieldName "weight" ;
+        rml:reference "$.weight" ;
+        ];
+    ] ;
+  ] .
+
+:triplesMapItem a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}/item/{item.type}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasWeight ;
+    rml:objectMap [
+      rml:reference "item.measures.weight" ;
+      rml:datatype xsd:integer ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice/item/sword> <http://example.org/hasWeight> "1500"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/person/alice/item/shield> <http://example.org/hasWeight> "2500"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/person/bob/item/flower> <http://example.org/hasWeight> "15"^^<http://www.w3.org/2001/XMLSchema#integer> .
+
+
+

14. RMLLVTC0003a

+

Title: Index Key: #

+

Description: Test a reference to the index key #

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasSequenceNumber ;
+    rml:objectMap [
+      rml:reference "#" ;
+      rml:datatype xsd:integer ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasSequenceNumber> "0"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/person/bob> <http://example.org/hasSequenceNumber> "1"^^<http://www.w3.org/2001/XMLSchema#integer> .
+
+
+

15. RMLLVTC0003b

+

Title: Index Key: Iterable Field

+

Description: Test a reference to the index key of an iterable field

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:IterableField ;
+    rml:fieldName "item" ;
+    rml:iterator "$.items[*]" ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "type" ;
+      rml:reference "$.type" ;
+    ] ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}/item/{item.#}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasType ;
+    rml:objectMap [
+      rml:reference "item.type" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice/item/0> <http://example.org/hasType> "sword" .
+<http://example.org/person/alice/item/1> <http://example.org/hasType> "shield" .
+<http://example.org/person/bob/item/0> <http://example.org/hasType> "flower" .
+
+
+
+

16. RMLLVTC0003c

+

Title: Index Key: Expression field

+

Description: Test a reference to the index key of an expression field

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        "sword",
+        "shield"
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        "flower"
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "item" ;
+    rml:reference "$.items[*]" ;
+  ] .
+
+:triplesMapItem a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}/item/{item.#}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasType ;
+    rml:objectMap [
+      rml:reference "item" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice/item/0> <http://example.org/hasType> "sword" .
+<http://example.org/person/alice/item/1> <http://example.org/hasType> "shield" .
+<http://example.org/person/bob/item/0> <http://example.org/hasType> "flower" .
+
+
+

17. RMLLVTC0004a

+

Title: Natural Datatype: Index #

+

Description: Test the natural datatype mapping for the index #

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasSequenceNumber ;
+    rml:objectMap [
+      rml:reference "#" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasSequenceNumber> "0"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/person/bob> <http://example.org/hasSequenceNumber> "1"^^<http://www.w3.org/2001/XMLSchema#integer> .
+
+
+

18. RMLLVTC0004b

+

Title: Natural Datatype: Index Expression Field

+

Description: Test the natural datatype mapping for the index of an expression field

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:IterableField ;
+    rml:fieldName "item" ;
+    rml:iterator "$.items[*]" ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "type" ;
+      rml:reference "$.type" ;
+    ] ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}/item/{item.type}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasSequenceNumber ;
+    rml:objectMap [
+      rml:reference "item.#" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice/item/sword> <http://example.org/hasSequenceNumber> "0"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/person/alice/item/shield> <http://example.org/hasSequenceNumber> "1"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/person/bob/item/flower> <http://example.org/hasSequenceNumber> "0"^^<http://www.w3.org/2001/XMLSchema#integer> .
+
+
+

19. RMLLVTC0004c

+

Title: Natural Datatype: Index Iterable Field

+

Description: Test the natural datatype mapping for the index of an iterable field

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        "sword",
+        "shield"
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        "flower"
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "item" ;
+    rml:reference "$.items[*]" ;
+  ] .
+
+:triplesMapItem a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}/item/{item}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasSequenceNumber ;
+    rml:objectMap [
+      rml:reference "item.#" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice/item/sword> <http://example.org/hasSequenceNumber> "0"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/person/alice/item/shield> <http://example.org/hasSequenceNumber> "1"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/person/bob/item/flower> <http://example.org/hasSequenceNumber> "0"^^<http://www.w3.org/2001/XMLSchema#integer> .
+
+
+

20. RMLLVTC0004d

+

Title: Natural Datatype: Record Expression Field

+

Description: Test the natural datatype mapping for a record of an expression field

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "birth_year": 1995
+    },
+    {
+      "name": "bob",
+      "birth_year": 1999
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "birthyear" ;
+    rml:reference "$.birth_year" ;
+  ] .
+
+:triplesMapItem a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasBirthYear ;
+    rml:objectMap [
+      rml:reference "birthyear" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasBirthYear> "1995"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/person/bob> <http://example.org/hasBirthYear> "1999"^^<http://www.w3.org/2001/XMLSchema#integer> .
+
+
+

21. RMLLVTC0005a

+

Title: Referencing a Non-Existing Key

+

Description: Test a reference to a non-existing key

+

Error expected? Yes

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{Name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasName ;
+    rml:objectMap [
+      rml:reference "Name" ;
+    ] ;
+  ] .
+
+
+

22. RMLLVTC0005b

+

Title: Referencing the Record Key

+

Description: Test a reference to the record key

+

Error expected? Yes

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :isDerivedFrom ;
+    rml:objectMap [
+      rml:reference "<it>" ;
+    ] ;
+  ] .
+
+
+

23. RMLLVTC0005c

+

Title: Referencing the Record Key of an Iterable Field

+

Description: Test a reference to the record key of an iterable field

+

Error expected? Yes

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:IterableField ;
+    rml:fieldName "item" ;
+    rml:iterator "$.items[*]" ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "type" ;
+      rml:reference "$.type" ;
+    ] ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasItem ;
+    rml:objectMap [
+      rml:template "http://example.org/person/{name}/{item}" ;
+    ] ;
+  ] .
+
+
+

24. RMLLVTC0006a

+

Title: Left Join

+

Description: Test a left join

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        "sword",
+        "shield"
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        "flower"
+      ]
+    }
+  ]
+}
+
+

Input 1

+
name,birthyear
+alice,1995
+bob,1999
+tobias,2005
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "item" ;
+    rml:reference "$.items[*]" ;
+  ] .
+
+:csvSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:csvView a rml:LogicalView ;
+  rml:viewOn :csvSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "birthyear" ;
+    rml:reference "birthyear" ;
+  ] ;
+  rml:leftJoin [
+    rml:parentLogicalView :jsonView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "json_item" ;
+      rml:reference "item" ;
+    ] ;
+  ] .
+
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :csvView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasBirthYear ;
+    rml:objectMap [
+      rml:reference "birthyear" ;
+      rml:datatype xsd:gYear ;
+    ] ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasItem ;
+    rml:objectMap [
+      rml:template "http://example.org/person/{name}/item/{json_item}" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasBirthYear> "1995"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+<http://example.org/person/alice> <http://example.org/hasItem> <http://example.org/person/alice/item/sword> .
+<http://example.org/person/alice> <http://example.org/hasItem> <http://example.org/person/alice/item/shield> .
+<http://example.org/person/bob> <http://example.org/hasBirthYear> "1999"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+<http://example.org/person/bob> <http://example.org/hasItem> <http://example.org/person/bob/item/flower> .
+<http://example.org/person/tobias> <http://example.org/hasBirthYear> "2005"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+
+
+

25. RMLLVTC0006b

+

Title: Inner Join

+

Description: Test an inner join

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        "sword",
+        "shield"
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        "flower"
+      ]
+    }
+  ]
+}
+
+

Input 1

+
name,birthyear
+alice,1995
+bob,1999
+tobias,2005
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "item" ;
+    rml:reference "$.items[*]" ;
+  ] .
+
+:csvSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:csvView a rml:LogicalView ;
+  rml:viewOn :csvSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "birthyear" ;
+    rml:reference "birthyear" ;
+  ] ;
+  rml:innerJoin [
+    rml:parentLogicalView :jsonView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "json_item" ;
+      rml:reference "item" ;
+    ] ;
+  ] .
+
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :csvView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasBirthYear ;
+    rml:objectMap [
+      rml:reference "birthyear" ;
+      rml:datatype xsd:gYear ;
+    ] ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasItem ;
+    rml:objectMap [
+      rml:template "http://example.org/person/{name}/item/{json_item}" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/alice> <http://example.org/hasBirthYear> "1995"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+<http://example.org/person/alice> <http://example.org/hasItem> <http://example.org/person/alice/item/sword> .
+<http://example.org/person/alice> <http://example.org/hasItem> <http://example.org/person/alice/item/shield> .
+<http://example.org/person/bob> <http://example.org/hasBirthYear> "1999"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+<http://example.org/person/bob> <http://example.org/hasItem> <http://example.org/person/bob/item/flower> .
+
+
+

26. RMLLVTC0006c

+

Title: Two Left Joins

+

Description: Test two left joins in one logical view

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        "sword",
+        "shield"
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        "flower"
+      ]
+    }
+  ]
+}
+
+

Input 1

+
name,birthyear
+alice,1995
+bob,1999
+tobias,2005
+
+

Input 2

+
name,id
+alice,123
+bob,456
+tobias,789
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "item" ;
+    rml:reference "$.items[*]" ;
+  ] .
+
+:additionalCsvSource a rml:LogicalSource ;
+  rml:source [
+   a rml:RelativePathSource , rml:Source ;
+   rml:root rml:MappingDirectory ;
+   rml:path "people2.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:additionalCsvView a rml:LogicalView ;
+  rml:viewOn :additionalCsvSource ;
+    rml:field [
+     a rml:ExpressionField ;
+     rml:fieldName "name" ;
+     rml:reference "name" ;
+    ] ;
+    rml:field [
+     a rml:ExpressionField ;
+     rml:fieldName "id" ;
+     rml:reference "id" ;
+    ] ;
+.
+
+:csvSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:csvView a rml:LogicalView ;
+  rml:viewOn :csvSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "birthyear" ;
+    rml:reference "birthyear" ;
+  ] ;
+  rml:leftJoin [
+    rml:parentLogicalView :jsonView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "json_item" ;
+      rml:reference "item" ;
+    ] ;
+  ] ;
+  rml:leftJoin [
+    rml:parentLogicalView :additionalCsvView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "csv2_id" ;
+      rml:reference "id" ;
+    ] ;
+  ] .
+
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :csvView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{csv2_id}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasBirthYear ;
+    rml:objectMap [
+      rml:reference "birthyear" ;
+      rml:datatype xsd:gYear ;
+    ] ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasItem ;
+    rml:objectMap [
+      rml:template "http://example.org/person/{csv2_id}/item/{json_item}" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/123> <http://example.org/hasBirthYear> "1995"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+<http://example.org/person/123> <http://example.org/hasItem> <http://example.org/person/123/item/sword> .
+<http://example.org/person/123> <http://example.org/hasItem> <http://example.org/person/123/item/shield> .
+<http://example.org/person/456> <http://example.org/hasBirthYear> "1999"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+<http://example.org/person/456> <http://example.org/hasItem> <http://example.org/person/456/item/flower> .
+<http://example.org/person/789> <http://example.org/hasBirthYear> "2005"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+
+
+

27. RMLLVTC0006d

+

Title: Inner Join and Left Join

+

Description: Test an inner join and a left join in one logical view

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        "sword",
+        "shield"
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        "flower"
+      ]
+    }
+  ]
+}
+
+

Input 1

+
name,birthyear
+alice,1995
+bob,1999
+tobias,2005
+
+

Input 2

+
name,id
+alice,123
+bob,456
+tobias,789
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "item" ;
+    rml:reference "$.items[*]" ;
+  ] .
+
+:additionalCsvSource a rml:LogicalSource ;
+  rml:source [
+   a rml:RelativePathSource , rml:Source ;
+   rml:root rml:MappingDirectory ;
+   rml:path "people2.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:additionalCsvView a rml:LogicalView ;
+  rml:viewOn :additionalCsvSource ;
+    rml:field [
+     a rml:ExpressionField ;
+     rml:fieldName "name" ;
+     rml:reference "name" ;
+    ] ;
+    rml:field [
+     a rml:ExpressionField ;
+     rml:fieldName "id" ;
+     rml:reference "id" ;
+    ] ;
+.
+
+:csvSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:csvView a rml:LogicalView ;
+  rml:viewOn :csvSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "birthyear" ;
+    rml:reference "birthyear" ;
+  ] ;
+  rml:innerJoin [
+    rml:parentLogicalView :jsonView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "json_item" ;
+      rml:reference "item" ;
+    ] ;
+  ] ;
+  rml:leftJoin [
+    rml:parentLogicalView :additionalCsvView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "csv2_id" ;
+      rml:reference "id" ;
+    ] ;
+  ] .
+
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :csvView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{csv2_id}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasBirthYear ;
+    rml:objectMap [
+      rml:reference "birthyear" ;
+      rml:datatype xsd:gYear ;
+    ] ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasItem ;
+    rml:objectMap [
+      rml:template "http://example.org/person/{csv2_id}/item/{json_item}" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/123> <http://example.org/hasBirthYear> "1995"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+<http://example.org/person/123> <http://example.org/hasItem> <http://example.org/person/123/item/sword> .
+<http://example.org/person/123> <http://example.org/hasItem> <http://example.org/person/123/item/shield> .
+<http://example.org/person/456> <http://example.org/hasBirthYear> "1999"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+<http://example.org/person/456> <http://example.org/hasItem> <http://example.org/person/456/item/flower> .
+
+
+

28. RMLLVTC0006e

+

Title: Two Inner Joins

+

Description: Test two left joins in one logical view

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        "sword",
+        "shield"
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        "flower"
+      ]
+    }
+  ]
+}
+
+

Input 1

+
name,birthyear
+alice,1995
+bob,1999
+tobias,2005
+
+

Input 2

+
name,id
+alice,123
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "item" ;
+    rml:reference "$.items[*]" ;
+  ] .
+
+:additionalCsvSource a rml:LogicalSource ;
+  rml:source [
+   a rml:RelativePathSource , rml:Source ;
+   rml:root rml:MappingDirectory ;
+   rml:path "people2.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:additionalCsvView a rml:LogicalView ;
+  rml:viewOn :additionalCsvSource ;
+    rml:field [
+     a rml:ExpressionField ;
+     rml:fieldName "name" ;
+     rml:reference "name" ;
+    ] ;
+    rml:field [
+     a rml:ExpressionField ;
+     rml:fieldName "id" ;
+     rml:reference "id" ;
+    ] ;
+.
+
+:csvSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:csvView a rml:LogicalView ;
+  rml:viewOn :csvSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "birthyear" ;
+    rml:reference "birthyear" ;
+  ] ;
+  rml:innerJoin [
+    rml:parentLogicalView :jsonView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "json_item" ;
+      rml:reference "item" ;
+    ] ;
+  ] ;
+  rml:innerJoin [
+    rml:parentLogicalView :additionalCsvView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "csv2_id" ;
+      rml:reference "id" ;
+    ] ;
+  ] .
+
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :csvView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{csv2_id}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasBirthYear ;
+    rml:objectMap [
+      rml:reference "birthyear" ;
+      rml:datatype xsd:gYear ;
+    ] ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasItem ;
+    rml:objectMap [
+      rml:template "http://example.org/person/{csv2_id}/item/{json_item}" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/123> <http://example.org/hasBirthYear> "1995"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+<http://example.org/person/123> <http://example.org/hasItem> <http://example.org/person/123/item/sword> .
+<http://example.org/person/123> <http://example.org/hasItem> <http://example.org/person/123/item/shield> .
+
+
+

29. RMLLVTC0006f

+

Title: Index Key of Field in Join

+

Description: Test references to indexes of fields from a join

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        "sword",
+        "shield"
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        "flower"
+      ]
+    }
+  ]
+}
+
+

Input 1

+
name,birthyear
+alice,1995
+tobias,2005
+bob,1999
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "item" ;
+    rml:reference "$.items[*]" ;
+  ] .
+
+:csvSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:csvView a rml:LogicalView ;
+  rml:viewOn :csvSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "birthyear" ;
+    rml:reference "birthyear" ;
+  ] ;
+  rml:innerJoin [
+    rml:parentLogicalView :jsonView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "json_item" ;
+      rml:reference "item" ;
+    ] ;
+  ] .
+
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :csvView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{#}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasBirthYear ;
+    rml:objectMap [
+      rml:reference "birthyear" ;
+      rml:datatype xsd:gYear ;
+    ] ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasItem ;
+    rml:objectMap [
+      rml:template "http://example.org/person/{#}/item/{json_item.#}/{json_item}" ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/person/0> <http://example.org/hasBirthYear> "1995"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+<http://example.org/person/0> <http://example.org/hasItem> <http://example.org/person/0/item/0/sword> .
+<http://example.org/person/0> <http://example.org/hasItem> <http://example.org/person/0/item/1/shield> .
+<http://example.org/person/2> <http://example.org/hasBirthYear> "1999"^^<http://www.w3.org/2001/XMLSchema#gYear> .
+<http://example.org/person/2> <http://example.org/hasItem> <http://example.org/person/2/item/0/flower> .
+
+
+
+

30. RMLLVTC0007a

+

Title: Change Reference Formulations: CSV including JSON array

+

Description: Test a change of reference formulations: csv source including json array

+

Error expected? No

+

Input

+
name,items
+alice,"[{""type"":""sword"",""weight"":1500},{""type"":""shield"",""weight"":2500}]"
+bob,"[{""type"":""flower"",""weight"":15}]"
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:mixedCSVSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:mixedCSVView a rml:LogicalView ;
+  rml:viewOn :mixedCSVSource ;
+  rml:field [
+    a rml:ExpressionField;
+    rml:fieldName "name" ;
+    rml:reference "name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "items" ;
+    rml:reference "items" ;
+    rml:field [
+      a rml:IterableField ;
+      rml:referenceFormulation rml:JSONPath ;
+      rml:iterator "$[*]" ;
+      rml:fieldName "item" ;
+      rml:field [
+        a rml:ExpressionField ;
+        rml:fieldName "type" ;
+        rml:reference "$.type" ;
+      ] ;
+      rml:field [
+        a rml:ExpressionField ;
+        rml:fieldName "weight" ;
+        rml:reference "$.weight" ;
+      ] ;
+    ] ;
+  ] .
+
+:triplesMapItem a rml:TriplesMap ;
+  rml:logicalSource :mixedCSVView ;
+  rml:subjectMap [
+    rml:template "http://example.org/item_{#}_{items.item.#}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasType ;
+    rml:objectMap [
+      rml:reference "items.item.type" ;
+    ] ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasWeight ;
+    rml:objectMap [
+      rml:reference "items.item.weight" ;
+      rml:datatype xsd:integer ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/item_0_0> <http://example.org/hasType> "sword" .
+<http://example.org/item_0_0> <http://example.org/hasWeight> "1500"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/item_0_1> <http://example.org/hasType> "shield" .
+<http://example.org/item_0_1> <http://example.org/hasWeight> "2500"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/item_1_0> <http://example.org/hasType> "flower" .
+<http://example.org/item_1_0> <http://example.org/hasWeight> "15"^^<http://www.w3.org/2001/XMLSchema#integer> .
+
+
+

31. RMLLVTC0007b

+

Title: Change Reference Formulations: CSV including JSON object

+

Description: Test a change of reference formulations: csv source including json object

+

Error expected? No

+

Input

+
name,item
+alice,"{""type"":""sword"",""weight"":1500}"
+alice,"{""type"":""shield"",""weight"":2500}"
+bob,"{""type"":""flower"",""weight"":15}"
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:mixedCSVSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:mixedCSVView a rml:LogicalView ;
+  rml:viewOn :mixedCSVSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "item" ;
+    rml:reference "item" ;
+    rml:field [
+      a rml:IterableField ;
+      rml:referenceFormulation rml:JSONPath ;
+      rml:iterator "$" ;
+      rml:fieldName "itemJson" ;
+      rml:field [
+        a rml:ExpressionField;
+        rml:fieldName "type" ;
+        rml:reference "$.type" ; ] ;
+      rml:field [
+        a rml:ExpressionField;
+        rml:fieldName "weight" ;
+        rml:reference "$.weight" ;
+      ] ;
+    ] ;
+  ] .
+
+:triplesMapItem a rml:TriplesMap ;
+  rml:logicalSource :mixedCSVView ;
+  rml:subjectMap [
+    rml:template "http://example.org/item_{#}_{item.#}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasType ;
+    rml:objectMap [
+      rml:reference "item.itemJson.type" ;
+    ] ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasWeight ;
+    rml:objectMap [
+      rml:reference "item.itemJson.weight" ;
+      rml:datatype xsd:integer ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/item_0_0> <http://example.org/hasType> "sword" .
+<http://example.org/item_0_0> <http://example.org/hasWeight> "1500"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/item_1_0> <http://example.org/hasType> "shield" .
+<http://example.org/item_1_0> <http://example.org/hasWeight> "2500"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/item_2_0> <http://example.org/hasType> "flower" .
+<http://example.org/item_2_0> <http://example.org/hasWeight> "15"^^<http://www.w3.org/2001/XMLSchema#integer> .
+
+
+

32. RMLLVTC0007c

+

Title: Change Reference Formulations: JSON including CSV

+

Description: Test a change of reference formulations: json source including csv data

+

Error expected? No

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": "type,weight\nsword,1500\nshield,2500"
+    },
+    {
+      "name": "bob",
+      "items": "type,weight\nflower,15"
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:mixedJSONSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:mixedJSONView a rml:LogicalView ;
+  rml:viewOn :mixedJSONSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+    ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "items" ;
+    rml:reference "$.items" ;
+    rml:field [
+      a rml:IterableField ;
+      rml:referenceFormulation rml:CSV ;
+      rml:fieldName "item";
+      rml:field [
+        a rml:ExpressionField ;
+        rml:fieldName "type" ;
+        rml:reference "type" ;
+      ] ;
+      rml:field [
+        a rml:expressionField ;
+        rml:fieldName "weight" ;
+        rml:reference "weight" ;
+      ] ;
+    ] ;
+  ].
+
+:triplesMapItem a rml:TriplesMap ;
+  rml:logicalSource :mixedJSONView ;
+  rml:subjectMap [
+    rml:template "http://example.org/item_{#}_{items.item.#}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasType ;
+    rml:objectMap [
+      rml:reference "items.item.type" ;
+    ] ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasWeight ;
+    rml:objectMap [
+      rml:reference "items.item.weight" ;
+      rml:datatype xsd:integer ;
+    ] ;
+  ] .
+
+

Output

+
<http://example.org/item_0_0> <http://example.org/hasType> "sword" .
+<http://example.org/item_0_0> <http://example.org/hasWeight> "1500"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/item_0_1> <http://example.org/hasType> "shield" .
+<http://example.org/item_0_1> <http://example.org/hasWeight> "2500"^^<http://www.w3.org/2001/XMLSchema#integer> .
+<http://example.org/item_1_0> <http://example.org/hasType> "flower" .
+<http://example.org/item_1_0> <http://example.org/hasWeight> "15"^^<http://www.w3.org/2001/XMLSchema#integer> .
+
+
+

33. RMLLVTC0008a

+

Title: Cycle: Abstract Logical Source

+

Description: Test a cycle in the abstract logical source of a logical view

+

Error expected? Yes

+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:view1 a rml:LogicalView ;
+  rml:viewOn :view2 ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name1" ;
+    rml:reference "name2" ;
+  ] .
+
+:view2 a rml:LogicalView ;
+  rml:viewOn :view1 ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name2" ;
+    rml:reference "name1" ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :view2 ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name2}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasName ;
+    rml:objectMap [
+      rml:reference "name2" ;
+    ] ;
+  ] .
+
+
+

34. RMLLVTC0008b

+

Title: Cycle: Joins

+

Description: Test a cycle in two joins of two logical views

+

Error expected? Yes

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        "sword",
+        "shield"
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        "flower"
+      ]
+    }
+  ]
+}
+
+

Input 1

+
name,birthyear
+alice,1995
+bob,1999
+tobias,2005
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "item" ;
+    rml:reference "$.items[*]" ;
+  ] ;
+  rml:leftJoin [
+    rml:parentLogicalView :csvView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "csv_birthyear" ;
+      rml:reference "birthyear" ;
+    ] ;
+  ] .
+
+:csvSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:csvView a rml:LogicalView ;
+  rml:viewOn :csvSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "birthyear" ;
+    rml:reference "birthyear" ;
+  ] ;
+  rml:leftJoin [
+    rml:parentLogicalView :jsonView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "json_item" ;
+      rml:reference "item" ;
+    ] ;
+  ] .
+
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :csvView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasBirthYear ;
+    rml:objectMap [
+      rml:reference "birthyear" ;
+      rml:datatype xsd:gYear ;
+    ] ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasItem ;
+    rml:objectMap [
+      rml:template "http://example.org/person/{name}/item/{json_item}" ;
+    ] ;
+  ] .
+
+
+

35. RMLLVTC0008c

+

Title: Cycle: Self-Join

+

Description: Test a cycle in a join of a logical view: self-join

+

Error expected? Yes

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:leftJoin [
+    rml:parentLogicalView :jsonView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "newName" ;
+      rml:reference "name" ;
+    ] ;
+  ] .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{newName}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasName ;
+    rml:objectMap [
+      rml:reference "newName" ;
+    ] ;
+  ] .
+
+
+

36. RMLLVTC0008d

+

Title: Cycle: Fields

+

Description: Test a cycle in nested fields

+

Error expected? Yes

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        {
+          "type": "sword",
+          "weight": 1500
+        },
+        {
+          "type": "shield",
+          "weight": 2500
+        }
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        {
+          "type": "flower",
+          "weight": 15
+        }
+      ]
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field :field1 .
+
+:field1 a rml:IterableField ;
+  rml:fieldName "item" ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.items[*]" ;
+  rml:field :field2.
+
+:field2 a rml:ExpressionField ;
+  rml:fieldName "type" ;
+  rml:reference "$.type" ;
+  rml:field :field1.
+
+
+

37. RMLLVTC0009a

+

Title: Name collision: between Fields with the same Parent

+

Description: Test a name collision between fields with the same parent

+

Error expected? Yes

+

Input

+
{
+  "people": [
+    {
+      "givenName": "Alice",
+      "familyName": "Smith"
+    },
+    {
+      "givenName": "Bob",
+      "familyName": "Johnson"
+    }
+  ]
+}
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.givenName" ;
+  ], [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.familyName" ;
+  ]  .
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :jsonView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasName ;
+    rml:objectMap [
+      rml:reference "name" ;
+    ] ;
+  ] .
+
+
+

38. RMLLVTC0009b

+

Title: Name collision: caused by Field from a Join

+

Description: Test a name collision caused by a field from a join

+

Error expected? Yes

+

Input

+
{
+  "people": [
+    {
+      "givenName": "alice",
+      "familyName": "smith",
+      "items": [
+        "sword",
+        "shield"
+      ]
+    },
+    {
+      "givenName": "bob",
+      "familyName": "johnson",
+      "items": [
+        "flower"
+      ]
+    }
+  ]
+}
+
+

Input 1

+
name,birthyear
+alice,1995
+bob,1999
+tobias,2005
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "givenName" ;
+    rml:reference "$.givenName" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "familyName" ;
+    rml:reference "$.familyName" ;
+  ] .
+
+:csvSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:csvView a rml:LogicalView ;
+  rml:viewOn :csvSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "birthyear" ;
+    rml:reference "birthyear" ;
+  ] ;
+  rml:leftJoin [
+    rml:parentLogicalView :jsonView ;
+    rml:joinCondition [
+      rml:parent "givenName" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "name" ;
+      rml:reference "familyName" ;
+    ] ; 
+  ] .
+
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :csvView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{name}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasBirthYear ;
+    rml:objectMap [
+      rml:reference "birthyear" ;
+      rml:datatype xsd:gYear ;
+    ] ;
+  ] .
+
+
+

39. RMLLVTC0009c

+

Title: Name collision: between Fields from different Joins

+

Description: Test a name collision between fields from different joins

+

Error expected? Yes

+

Input

+
{
+  "people": [
+    {
+      "name": "alice",
+      "items": [
+        "sword",
+        "shield"
+      ]
+    },
+    {
+      "name": "bob",
+      "items": [
+        "flower"
+      ]
+    }
+  ]
+}
+
+

Input 1

+
name,id
+alice,123
+bob,456
+tobias,789
+
+

Input 2

+
name,item
+alice,lantern
+bob,leaf
+
+

Mapping

+
@prefix rml: <http://w3id.org/rml/> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+@prefix : <http://example.org/> .
+
+:jsonSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.json" ;
+  ] ;
+  rml:referenceFormulation rml:JSONPath ;
+  rml:iterator "$.people[*]" .
+
+:jsonView a rml:LogicalView ;
+  rml:viewOn :jsonSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "$.name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "jsonitem" ;
+    rml:reference "$.items[*]" ;
+  ] .
+
+:additionalCsvSource a rml:LogicalSource ;
+  rml:source [
+   a rml:RelativePathSource , rml:Source ;
+   rml:root rml:MappingDirectory ;
+   rml:path "people2.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:additionalCsvView a rml:LogicalView ;
+  rml:viewOn :additionalCsvSource ;
+    rml:field [
+     a rml:ExpressionField ;
+     rml:fieldName "name" ;
+     rml:reference "name" ;
+    ] ;
+    rml:field [
+     a rml:ExpressionField ;
+     rml:fieldName "csvitem" ;
+     rml:reference "item" ;
+    ] ;
+.
+
+:csvSource a rml:LogicalSource ;
+  rml:source [
+    a rml:RelativePathSource , rml:Source ;
+    rml:root rml:MappingDirectory ;
+    rml:path "people.csv" ;
+  ] ;
+  rml:referenceFormulation rml:CSV .
+
+:csvView a rml:LogicalView ;
+  rml:viewOn :csvSource ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "name" ;
+    rml:reference "name" ;
+  ] ;
+  rml:field [
+    a rml:ExpressionField ;
+    rml:fieldName "id" ;
+    rml:reference "id" ;
+  ] ;
+  rml:leftJoin [
+    rml:parentLogicalView :jsonView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "item" ;
+      rml:reference "jsonitem" ;
+    ] ;
+  ] ;
+  rml:leftJoin [
+    rml:parentLogicalView :additionalCsvView ;
+    rml:joinCondition [
+      rml:parent "name" ;
+      rml:child "name" ;
+    ] ;
+    rml:field [
+      a rml:ExpressionField ;
+      rml:fieldName "item" ;
+      rml:reference "csvitem" ;
+    ] ;
+  ] .
+
+
+:triplesMapPerson a rml:TriplesMap ;
+  rml:logicalSource :csvView ;
+  rml:subjectMap [
+    rml:template "http://example.org/person/{id}" ;
+  ] ;
+  rml:predicateObjectMap [
+    rml:predicate :hasItem ;
+    rml:objectMap [
+      rml:template "http://example.org/person/{id}/item/{item}" ;
+    ] ;
+  ] .
+
+
+ + + + + \ No newline at end of file diff --git a/test-cases/docs/index.html b/test-cases/docs/index.html index c74314d..9cc552a 100644 --- a/test-cases/docs/index.html +++ b/test-cases/docs/index.html @@ -1,6 +1,6 @@ - +