Examples

rdf Nodes

How to use the different Node Types:

#include <rdf4cpp.hpp>


#include <iostream>

int main() {
    using namespace rdf4cpp;

    query::Variable variable("x");
    std::cout << variable << std::endl;

    query::Variable variable2("x1", true);
    std::cout << "variable2 =" << variable2 << std::endl;

    query::Variable variable3{"x1", true};
    std::cout << "variable3 =" << variable2 << std::endl;
    std::cout << "(variable 2 == variable3) = " << (variable2 == variable3) << std::endl;

    BlankNode blankNode("x1");
    std::cout << "blankNode =" << blankNode << std::endl;

    std::cout << "(variable2 != blankNode) = " << (variable2 != blankNode) << std::endl;

    IRI iri = IRI("http://example.com/");
    std::cout << iri << std::endl;

    IRI iri_pred("http://example.com/pred");
    std::cout << iri_pred << std::endl;

    auto print_literal_info = [](Literal lit) {
        std::cout << "---" << std::endl;
        std::cout << "operator<<: " << lit << std::endl;
        std::cout << "lexical_form: " << lit.lexical_form() << std::endl;
        std::cout << "datatype: " << lit.datatype() << std::endl;
        std::cout << "language_tag: " << lit.language_tag() << std::endl;
        std::cout << "---" << std::endl;
    };

    auto lit1 = Literal::make_simple("xxxx");
    auto lit2 = Literal::make_typed("xxxx", iri_pred);
    auto lit3 = Literal::make_typed("xxxx", IRI("http://example.com/pred2"));
    auto lit4 = Literal::make_lang_tagged("xxxx", "de");
    auto lit5 = Literal::make_lang_tagged("xxxx", "de");

    print_literal_info(lit1);
    print_literal_info(lit2);
    print_literal_info(lit3);
    print_literal_info(lit4);
    print_literal_info(lit5);

    std::vector<Node> nodes{};
    nodes.push_back(variable);
    nodes.push_back(variable2);
    nodes.push_back(blankNode);
    nodes.push_back(iri_pred);
    nodes.push_back(lit1);
    nodes.push_back(lit2);
    nodes.push_back(lit3);
    nodes.push_back(lit4);
    nodes.push_back(lit5);
    nodes.push_back(lit4.datatype());

    std::sort(nodes.begin(), nodes.end());
    std::cout << "sorted:" << std::endl;
    for (const auto &item : nodes) {
        std::cout << item << std::endl;
    }

    if (nodes[1].is_variable()) {
        auto v = nodes[1].as_variable();
        std::cout << v << std::endl;
    }
}

Literal Datatypes

How to use Literals and work with different Datatypes:

#include <rdf4cpp.hpp>
#include <cassert>

using namespace rdf4cpp;

void value_construction() {
    // runtime construction
    [[maybe_unused]] Literal float_1 = Literal::make_typed("1.1", IRI{"http://www.w3.org/2001/XMLSchema#float"});

    // using compile time knowledge
    [[maybe_unused]] Literal double_1 = Literal::make_typed_from_value<datatypes::xsd::Double>(1.2);

    // simplification: using user-defined-literal function
    [[maybe_unused]] Literal int_1 = 1_xsd_int;
}

void lexical_access() {
    Literal double_1 = 1.8_xsd_double;
    assert(double_1.lexical_form() == "1.8E0");
    assert(std::string{double_1} == R"#("1.8E0"^^<http://www.w3.org/2001/XMLSchema#double>)#");

    Literal lang_string = Literal::make_lang_tagged("Hello", "en-US");
    assert(lang_string.lexical_form() == "Hello");
    assert(lang_string.language_tag() == "en-us");
    assert(lang_string.language_tag_matches_range("*"));
    assert(lang_string.language_tag_matches_range("en"));
    assert(std::string{lang_string} == R"#("Hello"@en-us)#");
}

void direct_value_access() {
    Literal lit = 1.1_xsd_float;

    std::any rt_value = lit.value();
    assert(any_cast<float>(rt_value) == 1.1f);

    float ct_value = lit.value<datatypes::xsd::Float>();
    assert(ct_value == 1.1f);

    try {
        // invalid access
        lit.value<datatypes::xsd::Integer>();
        assert(false);
    } catch (std::runtime_error const &) {
    }
}

void value_transformations() {
    Literal lit = 42.0_xsd_float;
    assert(lit.value<datatypes::xsd::Float>() == 42.f);

    lit = lit * -1.5_xsd_float;
    assert(lit.value<datatypes::xsd::Float>() == -63.f);

    lit = lit.abs();
    assert(lit.value<datatypes::xsd::Float>() == 63.f);

    lit = lit.cast<datatypes::xsd::String>();
    assert(lit.value<datatypes::xsd::String>() == "63");

    lit = lit.as_ebv();
    assert(lit.value<datatypes::xsd::Boolean>() == true);
}

void comparisons() {
    Literal lit1 = 42.0_xsd_float;
    Literal lit2 = 89_xsd_int;
    Literal lit3 = 42_xsd_integer;

    assert(lit1 < lit2);
    assert(lit1 == lit3);
    assert(lit2 > lit3);
    assert(lit1.order(lit3) == std::partial_ordering::less);
}

int main() {
    value_construction();
    lexical_access();
    direct_value_access();
    value_transformations();
    comparisons();
}

Graphs and Datasets

How to build a Graph and perform some simple Queries on it:

#include <rdf4cpp.hpp>

#include <iostream>
#include <fstream>

int main(int argc, char *argv[]) {
    using namespace rdf4cpp;

    Dataset dataset;
    auto &g = dataset.graph(IRI{"http://named_graph.com"});

    g.add({IRI{"http://example.com"}, IRI{"http://example.com"}, Literal::make_lang_tagged("text", "en")});
    g.add({IRI{"http://example.com"}, IRI{"http://example.com"}, Literal::make_lang_tagged("text", "fr")});
    g.add({IRI{"http://example.com"}, IRI{"http://example.com"}, Literal::make_simple("txt")});
    g.add({IRI{"http://example.com"}, IRI{"http://example.com"}, Literal::make_simple("text")});

    dataset.add({IRI{"http://named_graph.com"}, IRI{"http://example.com"}, IRI{"http://example.com"}, Literal::make_simple("text")});

    query::TriplePattern triple_pattern{query::Variable("x"), IRI{"http://example.com"}, query::Variable{"z"}};
    std::cout << triple_pattern.subject() << std::endl;
    std::cout << triple_pattern.predicate() << std::endl;
    std::cout << triple_pattern.object() << std::endl;

    std::cout << "g size " << g.size() << std::endl;

    Graph::solution_sequence solutions = g.match(triple_pattern);
    for (const auto &solution : solutions) {
        std::cout << "bound variables: " << solution.bound_count() << std::endl;

        for (size_t i = 0; i < solution.bound_count(); ++i) {
            std::cout << solution.variable(i) << " -> " << solution[i] << std::endl;
        }
    }

    if (argc > 1) {
        Dataset ds2;
        std::ifstream ifs{argv[1]};
        if (!ifs.is_open()) {
            std::cout << "could not open test file." << std::endl;
            return 1;
        }

        ds2.load_rdf_data(ifs);

        std::cout << "ds2 from " << argv[1] << ":" << std::endl;
        std::cout << ds2 << std::endl;
    } else {
        std::cout << "no test file provided." << std::endl;
    }
}

Namespaces

How to use Namespaces to shorten IRIs:

#include <rdf4cpp.hpp>

#include <iostream>

int main() {
    using namespace rdf4cpp;

    Namespace ex("http://example.com/");

    IRI ex_A = ex + "A";
    std::cout << ex_A << std::endl;
    assert(ex_A.identifier() == "http://example.com/A");

    ex.clear();
    ex_A = ex + "A";
    std::cout << ex_A << std::endl;
    assert(ex_A.identifier() == "http://example.com/A");

    auto rdf = namespaces::RDF();
    auto rdf_Property = rdf + "Property";
    std::cout << rdf_Property << std::endl;
    assert(rdf_Property.identifier() == "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property");

    auto rdf_15 = rdf + "_15";
    std::cout << rdf_15 << std::endl;
    assert(rdf_15.identifier() == "http://www.w3.org/1999/02/22-rdf-syntax-ns#_15");
    try {
        [[maybe_unused]] auto random = rdf + "random";
    } catch (std::runtime_error const &ex) {
        std::cerr << ex.what() << std::endl;
    }
}

RDFFileParser

How to parse Turtle files:

#include <rdf4cpp.hpp>
#include <rdf4cpp/parser/RDFFileParser.hpp>

int main() {
    // read file
    for (const auto &v : rdf4cpp::parser::RDFFileParser{"./RDFFileParser_simple.ttl"}) {
        if (v.has_value())  // check if parser returns a successful read value
            std::cout << v.value() << "\n";
        else  // or an error
            std::cerr << v.error() << "\n";
    }
    return 0;
}