Façade-X mapping for XMLThis document specifies how an XML resource is represented as a Façade-X data source.
This is the editor's draft of this document. It changes with every update to the specification sources and is not a stable release. The latest release, version 0.1, is at https://w3c-facade-x.github.io/facade-x-specs/mapping-xml.html.
This document is a first draft. It follows the behaviour of the reference implementation, SPARQL Anything, and the test cases in facade-x-tests, as summarised in issue #31.
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:
An XML document is a tree of elements [XML]. Each element has a name, a set of attributes, and an ordered sequence of content: child elements and character data. Element and attribute names may belong to a namespace [XML-NAMES].
In Façade-X, each element is a container typed with the element name. Its attributes are held by string slots, and its content by numbered slots, in document order. Character data are values.
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# |
An engine MUST apply this mapping to a resource whose media type is application/xml or
text/xml [RFC7303], or any media type with the
structured syntax suffix +xml
(e.g. image/svg+xml), unless another format mapping applies to that media type.
When the media type is not given, an engine SHOULD apply this mapping to resources with the file
extensions xml and svg.
An XML resource yields exactly one data source. Its triples are placed in the named graph whose IRI
is the value of fxe:root.
The document element is represented by the root container,
which is typed both fx:Root and with the name of the document element.
The XML declaration, the document type declaration, and any comments and processing instructions outside the document element are not represented.
Element and attribute names are turned into IRIs as follows:
/ or #, a # is inserted between
them. For example, the element item in the namespace http://example.org/catalog gives
http://example.org/catalog#item, and dc:title, with dc bound to
http://purl.org/dc/elements/1.1/, gives http://purl.org/dc/elements/1.1/title.fxe:namespace, as defined in the
common principles. With the default namespace, person gives
xyz:person.As defined in [XML-NAMES], an unprefixed attribute has no namespace name, even
when a default namespace is declared: it is minted with fxe:namespace. The prefix xml is bound
to http://www.w3.org/XML/1998/namespace, so xml:lang gives
http://www.w3.org/XML/1998/namespace#lang.
Each element is represented by a container typed (rdf:type) with the IRI of the element name.
Each attribute of the element is held by a string slot whose IRI is the IRI of the attribute name.
Namespace declarations (xmlns and xmlns:* attributes) are not represented.
The content of the element is held by numbered slots, in document order: the first item in
rdf:_1, the second in rdf:_2, and so on. The items are:
A text node is a maximal sequence of character data between two pieces of markup. Character references, entity references and CDATA sections are replaced by the characters they stand for and are part of the surrounding text node.
The following are not represented, and do not use up a slot number:
An element with no attributes and no represented content gives a container that is only typed.
<empty/>, <empty></empty> and <empty> </empty> have the same representation.
XML without a schema defines no value types. Following the
common principles, every attribute value and text node is a literal of
type xsd:string, including values such as 10.50 or true. When fxe:xml.lang-tags is true,
values in the scope of xml:lang are language-tagged instead (see Language).
The lexical form of a text node is its character data, with whitespace kept: Text and tail
keep their spaces. Line ends are normalised as required by
XML 1.0 §2.11.
The lexical form of an attribute value is the value after
attribute-value normalisation. A line feed written as
the character reference is kept as a line feed.
By default, xml:lang is held by a string slot like any other attribute (see Names) and
has no other effect on the representation.
When fxe:xml.lang-tags is true, values are also language-tagged, following
the scope of xml:lang defined in XML 1.0 §2.12:
xml:lang attribute or, when it has none, the
language of its parent element. A document element without xml:lang has no language.xml:lang="" gives the element no language.xml:lang that is not a well-formed language tag [BCP47] is treated as
xml:lang="".xml:lang, xml:space, xml:base, xml:id) are not
language-tagged.xml:lang slot is kept.All other values are of type xsd:string.
The language of an element is determined by the XML source alone. Options that omit triples do
not change it: with fxe:null-string set to "", the slot for
xml:lang="" is omitted, but the element still has no language.
These options are terms of the Engine vocabulary and apply only to this mapping.
| Term | Range | Default | Description |
|---|---|---|---|
fxe:xml.path |
xsd:string |
— | An XPath expression [XPATH]. Only the nodes it selects, and their content, are represented. |
fxe:xml.lang-tags |
xsd:boolean |
false | Language-tag text nodes and attribute values in the scope of xml:lang (see Language). |
The reference implementation accepts several values for xml.path as numbered options
(xml.path.1, xml.path.2, …). Whether this form is kept is open.
An engine SHOULD NOT retrieve external entities or external DTD subsets referenced by a document, since doing so can disclose local files or cause requests to other hosts.
Input:
<?xml version="1.0" encoding="UTF-8"?>
<person id="p1">
<name>Alice</name>
</person>
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, xyz:person ;
xyz:id "p1" ;
rdf:_1 [ a xyz:name ; rdf:_1 "Alice" ] .
The whitespace between the elements gives no text nodes.
Input:
<catalog xmlns="http://example.org/catalog"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:ex="http://example.org/ext"
version="1.0" xml:lang="en">
<dc:title>Sample catalog</dc:title>
<item id="i1" ex:status="active">
<price currency="EUR">10.50</price>
</item>
</catalog>
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/> .
@prefix cat: <http://example.org/catalog#> .
@prefix ex: <http://example.org/ext#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
[] a fx:Root, cat:catalog ;
xyz:version "1.0" ;
<http://www.w3.org/XML/1998/namespace#lang> "en" ;
rdf:_1 [ a dc:title ; rdf:_1 "Sample catalog" ] ;
rdf:_2 [ a cat:item ;
xyz:id "i1" ;
ex:status "active" ;
rdf:_1 [ a cat:price ; xyz:currency "EUR" ; rdf:_1 "10.50" ] ] .
The elements take the default namespace, but the unprefixed attributes version, id and
currency do not.
Input:
<doc>
<mixed>Text <b>bold</b> and <i>italic</i> tail</mixed>
<!-- a comment -->
<empty/>
<whitespace> </whitespace>
</doc>
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, xyz:doc ;
rdf:_1 [ a xyz:mixed ;
rdf:_1 "Text " ;
rdf:_2 [ a xyz:b ; rdf:_1 "bold" ] ;
rdf:_3 " and " ;
rdf:_4 [ a xyz:i ; rdf:_1 "italic" ] ;
rdf:_5 " tail" ] ;
rdf:_2 [ a xyz:empty ] ;
rdf:_3 [ a xyz:whitespace ] .
The comment does not use up a slot number, so empty is held by rdf:_2.
Input, with fxe:xml.lang-tags set to true:
<doc xml:lang="en">
<title>Colour</title>
<title xml:lang="it" note="variante">Colore</title>
<code xml:lang="">RGB</code>
</doc>
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, xyz:doc ;
<http://www.w3.org/XML/1998/namespace#lang> "en" ;
rdf:_1 [ a xyz:title ; rdf:_1 "Colour"@en ] ;
rdf:_2 [ a xyz:title ;
<http://www.w3.org/XML/1998/namespace#lang> "it" ;
xyz:note "variante"@it ;
rdf:_1 "Colore"@it ] ;
rdf:_3 [ a xyz:code ;
<http://www.w3.org/XML/1998/namespace#lang> "" ;
rdf:_1 "RGB" ] .
The first title inherits en from doc; the second overrides it with it, which also applies to
its attribute note. In code, xml:lang="" removes the language. The xml:lang values
themselves are not tagged. With the default, fxe:xml.lang-tags set to false, all these values
are of type xsd:string.
Listing the items of the catalog with their price:
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 rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX cat: <http://example.org/catalog#>
SELECT ?id ?price WHERE {
SERVICE <x-sparql-anything:> {
fx:properties fxe:location "catalog.xml" .
?item a cat:item ;
xyz:id ?id ;
?slot ?p .
?p a cat:price ;
rdf:_1 ?price .
}
}