ExpertFinder 2fmappings
From FOAF
Contents |
[edit] Mappings
On this page we aim to provide an evolving list of mappings between terms of different vocabularies relevant to ExpertFinder as outlined in a draft paper by initiative members.
Since there is no proper W3C standard available yet for a rules language allowing to specify such mapping definitions, we will use slightly extended SPARQL CONSTRUCT statements and explaining text in natural language.
The list is still incomplete and preliminary, but the examples below show the desparate need for a standardized rule language on top of RDF: As we will demonstrate, simple mappings between vCard and FOAF already are not only beyond OWL or RDFS subclass or subproperty definitions, but even beyond what is expressible in the current version of SPARQL by means of CONSTRUCT statements.
[edit] Mappings between FOAF and vCard
We start with mappings between terms in vCard and FOAF. A table outlining overlaps is loosely based on previous work by Harry Halpin . These tables mention the original vCard RDF vocabulary, an alternative vCard ontololy by Harry Halpin et al., FOAF, W3C Pim and DOAC.
We start here with relations between vCard/RDF and FOAF.
[edit] Names
1. AvCard:FNis a
foaf:name. (but not necessarily the other way around).
CONSTRUCT { ?X foaf:name ?FN . }
WHERE { ?X vCard:FN ?FN . FILTER isLiteral(?FN) }
The FILTER expression here, may be viewed as kind of "type checking".1. A
vCard:nis a
foaf:name. This one is more tricky, vCard name consists of a substructure consisting of
Familyname,
Givenname,
Othernames, honorific
Prefixes, and honorific
Suffixes. In our mapping we suggest, that all these concatenated constitute a
foaf:namesof the respective person or entity:
CONSTRUCT { ?X foaf:name ?Name . }
WHERE { ?X vCard:N ?N .
OPTIONAL {?N vCard:Family ?Fam . }
OPTIONAL {?N vCard:Given ?Giv . }
OPTIONAL {?N vCard:Other ?Oth . }
OPTIONAL {?N vCard:Given ?Prefix . }
OPTIONAL {?N vCard:Given ?Suffix . }
FILTER ( ?Name = fn:concat(?Prefix, " ",
?Giv, " ",
?Fam, " ",
?Oth, " ",
?Suffix, ) ) }
We observe the following problem here: First, we use FILTERs here for constructing a new binding which is not covered by the current SPARQL specification, since FILTER expressions are not meant to create new bindings of variables (in this case the variable ?Name), but only filter existing bindings. Second, if we'd want to model the case where e.g. several other names were provided, we'd need a kind of aggregate function to "collect" them in a single variable, which is also beyond the current Spec. Also, we would admittedly have to slightly "abuse"
fn:concathere assuming that unbound variables are just replaced by an empty string, when one of the parts of the name structure is not defined. 1. Finally, for
Givenand
Familynames there exist own properties in FOAF, where we can define bidirectional mappings. (We keep on using SPARQL CONSTRUCTs here, but note that we could also use
rdfs:subpropertydeclarations for such simple cases. However, subproperty relations are not considered in the current SPARQL spec which only deals with RDF simple entailments).
CONSTRUCT { ?X foaf:surname ?Fam . }
WHERE { ?X vCard:N ?N . ?N vCard:Family ?Fam . FILTER isLiteral(?Fam) }
CONSTRUCT { ?X foaf:givenname ?Given . }
WHERE { ?X vCard:N ?N . ?N vCard:Given ?Given . FILTER isLiteral(?Given) }
As a final remark here we note that FOAF's naming properties such as foaf:surname,
foaf:givenname,
foaf:firstNameare all declared "testing" in the FOAF spec. We hope that the open issues in this respect are soon resolved.
[edit] Telephone and Fax numbers
1. AvCard:TELis a
foaf:phone: More precicely,
vCard:TELis related to
foaf:phoneas follows. We have to create a URI from the RDF literal value defining
vCard:telhere, since vCard stores Telephone numbers as string literals, whereas FOAF uses resources, i.e., URIs with the
tel:uri scheme.
CONSTRUCT { ?X foaf:phone ?T . }
WHERE { ?X vCard:TEL ?T1 .
FILTER ( isURI(?T) && isLiteral(?T1) &&
fn:str(?T) = fn:concat("tel:",fn:encode-for-uri(?T1)) ) }
Lacking a standard language to define complex mappings as this one, we admittedly "abuse" SPARQL FILTER expressions here again for data conversion, which is likely not (yet?) supported by any curent engine, and actually here we would need some kind of constraint solver functionality. We hope that the RIF WG will come up with a solution which allows more adequate rules language for future versions of this document, since they actually are discussing modeling CLP style constraints in rules at the moment. The main problem in this example is that function symbols are not allowed in the CONSTRUCT part, which would solve our concrete problem here:
CONSTRUCT { ?X foaf:phone fn:str2URI(fn:concat("tel:",fn:encode-for-uri(?T)) . }
WHERE { ?X vCard:TEL ?T . }
vCard:N,
vCard:TELmay be specified in with a substructure, outlining different phone number types such as fax, voice, home, etc. So, we additionally provide a refined mapping for the above, which maps
TELs of type fax to
foaf:phoneusing the
faxURI scheme:
CONSTRUCT { ?X foaf:phone ?T . }
WHERE { ?X vCard:TEL ?Fax .
?Fax a <http://www.w3.org/2001/vcard-rdf/3.0#fax"> .
?Fax rdf:value ?Val .
FILTER ( isURI(?T) &&
&& isLiteral{?Val}
fn:str(?T) = fn:concat("fax:",fn:encode-for-uri(?Val)) ) }
CONSTRUCT { ?X foaf:phone ?T . }
WHERE { ?X vCard:TEL ?Tel .
?Tel rdf:value ?Val .
OPTIONAL { ?T1 a <http://www.w3.org/2001/vcard-rdf/3.0#fax">
FILTER ?Tel = ?T1 .}
FILTER ( ! bound(?T1) &&
isURI(?T) &&
&& isLiteral{?Val}
fn:str(?T) = fn:concat("tel:",fn:encode-for-uri(?Val)) ) }
The second of these two rules uses negation as failure (by means of the combination of OPRIONALand
! bound) in order to use the
tel:URI scheme only for
telephone numbers which are not explicitly declared to be fax numbers.
foaf:phoneusing the the
tel:uri scheme is a
vCard:TEL:
CONSTRUCT { ?X vCard:TEL ?T . }
WHERE { ?X foaf:phone ?T1 .
FILTER ( fn:substring(fn:str(?T1),0,4) = "tel:" &&
?T = fn:substring(fn:str(?T1),5) ) }
1. A foaf:phoneusing the the
fax:uri scheme is a
vCard:TELof type
fax:
CONSTRUCT { ?X vCard:FAX ?Fax .
?Fax a <http://www.w3.org/2001/vcard-rdf/3.0#fax"> .
?Fax rdf:value ?T}
WHERE { ?X foaf:phone ?T1 .
FILTER ( fn:substring(fn:str(?T1),0,4) = "fax:" &&
?T = fn:substring(fn:str(?T1),5) ) }
[edit] Birthday information
FOAF expresses a Birthday by only in mm-dd string form, whereas vCard also specifies the year. Again we need string manipulation to define the appropriate mappings, and actually we can only map from vCard to FOAF, but not the other way around:
CONSTRUCT { ?X foaf:birthday ?Birthday . }
WHERE { ?X vCard:BDAY ?BDAY .
FILTER ( ?Birthday = fn:substring(fn:str(?BDAY),6) ) }
This mapping works under the assumption that the vCard birthday is indeed stored in yyyy-mm-dd format. If we want to make sure, we better add additional FILTER conditions to make this mapping rule waterproof.
[edit] Adresses
--- TBD: complete the list of mappings, where clear! ---
