Hisashi Sakai
Hisashi Sakai

Reputation: 65

How to select a property according to a condition in RDF

In the following RDF sample, I would like to get a value of one of properties according to a condition. The condition is below:

@prefix ex: <http://www.example.org#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

ex:mail1
  ex:sender "John"^^xsd:string ;
  ex:receiver "Bill"^^xsd:string ;
  ex:paymentType ex:paymentType1 .

ex:mail2
  ex:sender "Jack"^^xsd:string ;
  ex:receiver "Tom"^^xsd:string ;
  ex:paymentType ex:paymentType2 .

ex:paymentType1
  ex:paymentTypeDescription "PREPAID"^^xsd:string ;
  ex:referProperty "ex:sender"^^xsd:string .

ex:paymentType2
  ex:paymentTypeDescription "COLLECT"^^xsd:string ;
  ex:referProperty "ex:receiver"^^xsd:string .

Sparql to get a value is below:

PREFIX ex:<http://ww....ex#>
SELECT ?mail ?refProp ?payer
WHERE
{
    {
        SELECT ?mail ?refProp
        WHERE
        {
            ?mail ex:paymentType / ex:referProperty ?refProp.
        }
    }
    ?mail ?refProp ?payer.
}

It is possible to get a value by the Sparql. But I question that the way using the above RDF sample and Sparql is irregular, because it seems to extends outside first-order predicate logic. Using a value which was gotten from literal node as a variable to search a property is irregular. In theory, property”ex:referProperty” should be defined in RDFS. Do you think so? If you think so, teach me a regular way which includes right RDF and right Sparql.

Upvotes: 1

Views: 712

Answers (1)

Stanislav Kralin
Stanislav Kralin

Reputation: 11479

Option 1

One can transform URIs to strings and vice versa using STR(), IRI() and REPLACE():

PREFIX ex: <http://www.example.org#>
SELECT ?mail ?str ?payer {
   ?mail ?p ?payer; ex:paymentType/ex:referProperty ?str.
   FILTER (replace(str(?p), str(ex:), "ex:") = ?str)
}

or

PREFIX ex: <http://www.example.org#>
SELECT ?mail ?str ?payer {
   ?mail ?p ?payer; ex:paymentType/ex:referProperty ?str.
   FILTER (URI(replace(?str, "ex:", str(ex:))) = ?p)
}

Option 2

You can implement your conditions using BIND and IF:

PREFIX ex: <http://www.example.org#>
SELECT ?mail ?str ?payer {
   ?mail ex:paymentType/ex:referProperty ?str.
   BIND (IF(?str = "ex:sender", ex:sender, ex:receiver) AS ?p)
   ?mail ?p ?payer.
}

Option 3

Use VALUES:

PREFIX ex: <http://www.example.org#>
SELECT ?mail ?str ?payer {
    VALUES (?str ?uri) {("ex:sender" ex:sender) ("ex:receiver" ex:receiver)}
    ?mail ?uri ?payer; ex:paymentType/ex:referProperty ?str.
}

Option 4

As suggested by Damyan Ognyanov, you could use URIs instead of strings in your reference data, i. e. ex:sender instead of "ex:sender" etc. Then your query will be simply the following:

PREFIX ex: <http://www.example.org#>
SELECT ?mail ?str ?payer {
    ?mail ?uri ?payer; ex:paymentType/ex:referProperty ?uri.
}

Update

From your comment:

Isn’t using ex:sender as property and object in one RDF contradiction? Using ex:sender as URI in RDF makes the border between RDF an RDFS dubious.

From RDF 1.1 Concepts and Abstract Syntax:

The set of nodes of an RDF graph is the set of subjects and objects of triples in the graph.
It is possible for a predicate IRI to also occur as a node in the same graph.

In RDF, "properties" (or rather their "types") are first-class objects.
RDFS is rather a vocabulary (which introduces e. g. the notion of rdf:Property) than a schema.
There is no clear distinction between "ABox" and "TBox" in RDF.

Upvotes: 1

Related Questions