Façade-X mapping for CSV
Copyright
©
2026
the Contributors to the Façade-X mapping for CSV
Specification, published by the
Data Façades Community Group under the
W3C Community Contributor License Agreement (CLA). A human-readable
summary
is available.
This document specifies how a CSV resource is represented as a Façade-X data source.
This specification was published by the Data Façades 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 version 0.1 of this document, released on 2026-10-06, at https://w3c-facade-x.github.io/facade-x-specs/0.1/mapping-csv.html. This version will not change. The latest release is always at https://w3c-facade-x.github.io/facade-x-specs/mapping-csv.html. The editor's draft, which may include changes made after this release, is at https://w3c-facade-x.github.io/facade-x-specs/dev/mapping-csv.html. The issues addressed in this release, and those still open, are listed in the release notes.
This document is a first draft. It follows the behaviour of the reference implementation, SPARQL Anything, and the test cases in facade-x-tests.
GitHub Issues are preferred for discussion of this specification.
This document is listed in Façade-X Mappings, one of the seven Façade-X specification documents produced by the Data Façades Community Group:
This section is non-normative.
A CSV resource is a sequence of records, and each record is a sequence of fields [RFC4180]. In Façade-X, the resource is a root container holding one container per record. A record container holds its fields either by position or, when headers are used, by column name.
This document applies the common principles of the format mappings.
| Prefix | Namespace |
|---|---|
| fx | http://sparql.xyz/facade-x/ns/ |
| fxe | http://sparql.xyz/facade-x/engine/ |
| xyz | http://sparql.xyz/facade-x/data/ |
| rdf | http://www.w3.org/1999/02/22-rdf-syntax-ns# |
The treatment of records with empty lines is not yet specified.
The treatment of files with duplicate header names, is not yet specified.
The treatment of records with more fields than the header row, is not yet specified.
When fxe:csv.headers-row is greater than 1, whether the records before the header row are represented is not yet specified.
fxe:csv.null-string has the same effect as the general option fxe:null-string. It is kept for compatibility with the reference implementation; whether both are needed is open.
An engine MUST apply this mapping to a resource whose media type is one of:
text/csvtext/tab-separated-valuesWhen the media type is not given, an engine SHOULD apply this mapping to resources with the file
extensions csv, tsv, and tab. For text/tab-separated-values and for the extensions tsv and
tab, the default delimiter is the tab character.
A CSV resource yields exactly one data source. Its triples are placed in the named graph whose IRI
is the value of fxe:root.
The data source has one root container, typed fx:Root.
Each record is represented by a container. The root container holds the record containers in
numbered slots, in the order of the records in the resource: the first record in rdf:_1, the
second in rdf:_2, and so on.
When fxe:csv.headers is true, the header row is not represented as a record and
the numbering starts from the first record after it.
A resource with no records yields a root container with no slots.
When fxe:csv.headers is false, each field is held by a numbered slot of its record container,
in the order of the fields in the record: the first field in rdf:_1, the second in rdf:_2, and
so on.
When fxe:csv.headers is true, each field is held by a string slot. The slot IRI is minted from
the header of the field's column, as defined in the common principles.
With the default namespace, a column headed name gives the slot xyz:name.
When fxe:csv.ignore-columns-with-no-header is true,
fields in columns without a header are not represented.
Each field value is a literal of type xsd:string. CSV defines no value types, so no other
datatype is used.
The lexical form of the literal is the content of the field after parsing:
fxe:trim-strings
is true.An empty field, quoted or not, is represented by the empty string "". It is not omitted, unless
it matches fxe:null-string or fxe:csv.null-string.
These options are terms of the Engine vocabulary and apply only to this mapping.
| Term | Range | Default | Description |
|---|---|---|---|
fxe:csv.headers |
xsd:boolean |
false | Use the values of the header row to mint slot IRIs for the fields. |
fxe:csv.headers-row |
xsd:positiveInteger |
1 | The number of the row that holds the headers. |
fxe:csv.delimiter |
xsd:string |
, (tab for tab-separated values) |
The single character that separates fields. |
fxe:csv.quote-char |
xsd:string |
" |
The single character that encloses fields. An empty string disables quoting. |
fxe:csv.null-string |
xsd:string |
— | Omit fields whose value equals the given string. |
fxe:csv.ignore-columns-with-no-header |
xsd:boolean |
false | Omit fields in columns that have no header. |
The reference implementation also supports csv.format, which selects a predefined format of the
Apache Commons CSV library, and csv.headers.sanitize. These are not part of this specification.
This section is non-normative.
Input:
name,age
Alice,30
Bob,25
Façade-X representation, with default options:
@prefix fx: <http://sparql.xyz/facade-x/ns/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
[] a fx:Root ;
rdf:_1 [ rdf:_1 "name" ; rdf:_2 "age" ] ;
rdf:_2 [ rdf:_1 "Alice" ; rdf:_2 "30" ] ;
rdf:_3 [ rdf:_1 "Bob" ; rdf:_2 "25" ] .
The same input, with fxe:csv.headers set to true:
@prefix fx: <http://sparql.xyz/facade-x/ns/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xyz: <http://sparql.xyz/facade-x/data/> .
[] a fx:Root ;
rdf:_1 [ xyz:name "Alice" ; xyz:age "30" ] ;
rdf:_2 [ xyz:name "Bob" ; xyz:age "25" ] .
Input, with fxe:csv.headers set to true:
id,name,notes
2,"Bob, Jr.",""
3,"Carol ""CJ"" Jones",
4,Dan,"first line
second line"
Façade-X representation:
@prefix fx: <http://sparql.xyz/facade-x/ns/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xyz: <http://sparql.xyz/facade-x/data/> .
[] a fx:Root ;
rdf:_1 [ xyz:id "2" ; xyz:name "Bob, Jr." ; xyz:notes "" ] ;
rdf:_2 [ xyz:id "3" ; xyz:name "Carol \"CJ\" Jones" ; xyz:notes "" ] ;
rdf:_3 [ xyz:id "4" ; xyz:name "Dan" ; xyz:notes "first line\nsecond line" ] .
Selecting the names of people older than 26:
PREFIX fx: <http://sparql.xyz/facade-x/ns/>
PREFIX fxe: <http://sparql.xyz/facade-x/engine/>
PREFIX xyz: <http://sparql.xyz/facade-x/data/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?name WHERE {
SERVICE <x-sparql-anything:> {
fx:properties fxe:location "people.csv" ;
fxe:csv.headers true .
?record xyz:name ?name ;
xyz:age ?age .
FILTER (xsd:integer(?age) > 26)
}
}
This section is non-normative.