{"id":13781131,"url":"https://github.com/carml/carml","last_synced_at":"2026-01-11T17:01:29.283Z","repository":{"id":37432292,"uuid":"104094274","full_name":"carml/carml","owner":"carml","description":"A pretty sweet RML engine, for RDF.","archived":false,"fork":false,"pushed_at":"2025-11-13T06:02:33.000Z","size":2932,"stargazers_count":109,"open_issues_count":22,"forks_count":20,"subscribers_count":14,"default_branch":"main","last_synced_at":"2025-11-13T07:19:23.313Z","etag":null,"topics":["linked-data","r2rml","r2rml-mapping","rdf","rml","rml-mapping","rml-spec","semantic-web"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/carml.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-09-19T15:38:54.000Z","updated_at":"2025-11-13T06:02:35.000Z","dependencies_parsed_at":"2023-02-12T06:00:45.884Z","dependency_job_id":"bc8582d5-a22a-495a-8d7e-926b6f77125a","html_url":"https://github.com/carml/carml","commit_stats":null,"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"purl":"pkg:github/carml/carml","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carml%2Fcarml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carml%2Fcarml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carml%2Fcarml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carml%2Fcarml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/carml","download_url":"https://codeload.github.com/carml/carml/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carml%2Fcarml/sbom","scorecard":{"id":266476,"data":{"date":"2025-08-11","repo":{"name":"github.com/carml/carml","commit":"4170573845a18796e39f54e9236ccb954392b7d8"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5,"checks":[{"name":"Code-Review","score":-1,"reason":"Found no human activity in the last 30 changesets","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"20 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build.yml:1","Warn: no topLevel permission defined: .github/workflows/release-with-input.yml:1","Warn: no topLevel permission defined: .github/workflows/reloc-release-with-input.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/carml/carml/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/carml/carml/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/carml/carml/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-with-input.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/carml/carml/release-with-input.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-with-input.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/carml/carml/release-with-input.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-with-input.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/carml/carml/release-with-input.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/reloc-release-with-input.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/carml/carml/reloc-release-with-input.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/reloc-release-with-input.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/carml/carml/reloc-release-with-input.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/reloc-release-with-input.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/carml/carml/reloc-release-with-input.yml/main?enable=pin","Info:   0 out of   9 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: MIT License: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'","Warn: branch protection not enabled for branch 'experimental'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":10,"reason":"SAST tool detected","details":["Info: SAST configuration detected: Sonar","Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":5,"reason":"5 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-h46c-h94j-95f3","Warn: Project is vulnerable to: GHSA-735f-pc8j-v9w8","Warn: Project is vulnerable to: GHSA-4265-ccf5-phj5","Warn: Project is vulnerable to: GHSA-4g9r-vxhx-9pgx","Warn: Project is vulnerable to: GHSA-j288-q9x7-2f5v"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T12:10:35.262Z","repository_id":37432292,"created_at":"2025-08-17T12:10:35.262Z","updated_at":"2025-08-17T12:10:35.262Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28314259,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T14:58:17.114Z","status":"ssl_error","status_checked_at":"2026-01-11T14:55:53.580Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linked-data","r2rml","r2rml-mapping","rdf","rml","rml-mapping","rml-spec","semantic-web"],"created_at":"2024-08-03T18:01:23.226Z","updated_at":"2026-01-11T17:01:29.207Z","avatar_url":"https://github.com/carml.png","language":"Java","readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://raw.githubusercontent.com/carml/carml.github.io/master/carml-logo.png\" height=\"100\" alt=\"carml\"\u003e\n\u003c/p\u003e\n\nCARML\n=====================\n**A pretty sweet RML engine**\n\n[![Build](https://github.com/carml/carml/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/carml/carml/actions/workflows/build.yml)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.carml/carml/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.carml/carml)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=io.carml%3Acarml\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=io.carml%3Acarml)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=io.carml%3Acarml\u0026metric=coverage)](https://sonarcloud.io/dashboard?id=io.carml%3Acarml)\n\nTable of Contents\n-----------------\n\n- [Introduction](#introduction)\n- [Getting started](#getting-started)\n- [Reactive streams](#reactive-streams)\n- [Support for Apache Jena](#support-for-apache-jena)\n- [Input stream extension](#input-stream-extension)\n- [Function extension](#function-extension)\n- [XML namespace extension](#xml-namespace-extension)\n- [CARML in RML Test Cases](#carml-in-rml-test-cases)\n- [Projects using CARML](#projects-using-carml)\n- [About CARML](#about-carml)\n\nIntroduction\n------------\nCARML is a java library that transforms structured sources to RDF as declared in an [RML](http://rml.io) mapping,\nin accordance with the [RML spec](http://rml.io/spec.html).\n\nThe best place to start learning about RML is at the [source](http://rml.io), but basically RML is defined as a superset\nof [R2RML](https://www.w3.org/TR/r2rml/) which is a W3C recommendation that describes a language for expressing mappings\nfrom relational databases to RDF datasets. RML allows not only the expression of mappings for relational databases, but\ngeneralizes this to any structured source. All you need is a way to iterate over and query the source.\n\n\u003e NOTE: If you have questions about RML in general, the best place to ask them is at\n\u003e [RML questions](https://github.com/kg-construct/rml-questions).\n\nGetting started\n---------------\n\nCARML is available as a runnable jar with CLI: [CARML jar](https://github.com/carml/carml-jar).\n\nCARML is also available from the Central Maven Repository.\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.carml\u003c/groupId\u003e\n    \u003cartifactId\u003ecarml-engine\u003c/artifactId\u003e\n    \u003cversion\u003e${carml.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n    \u003c!-- Choose the resolvers to suit your need --\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.carml\u003c/groupId\u003e\n    \u003cartifactId\u003ecarml-logical-source-resolver-jsonpath\u003c/artifactId\u003e\n    \u003cversion\u003e${carml.version}\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.carml\u003c/groupId\u003e\n    \u003cartifactId\u003ecarml-logical-source-resolver-xpath\u003c/artifactId\u003e\n    \u003cversion\u003e${carml.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.carml\u003c/groupId\u003e\n    \u003cartifactId\u003ecarml-logical-source-resolver-csv\u003c/artifactId\u003e\n    \u003cversion\u003e${carml.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n```\n\nExample usage:\n\n```java\nSet\u003cTriplesMap\u003e mapping = RmlMappingLoader.build()\n    .load(RDFFormat.TURTLE, Paths.get(\"path-to-mapping-file\"));\n\nRdfRmlMapper mapper = RdfRmlMapper.builder()\n    // add mappings\n    .triplesMaps(mapping)\n    // Add the resolvers to suit your need\n    .setLogicalSourceResolver(Rdf.Ql.JsonPath, JsonPathResolver::getInstance)\n    .setLogicalSourceResolver(Rdf.Ql.XPath, XPathResolver::getInstance)\n    .setLogicalSourceResolver(Rdf.Ql.Csv, CsvResolver::getInstance)\n    //-- optional: --\n    // specify base IRI to use for relative IRIs in mapping results\n    // default is \"http://example.com/base/\"\n    .baseIri(\"http://foo.bar\")\n    // specify IRI unicode normalization form (default = NFC)\n    // see http://www.unicode.org/unicode/reports/tr15/tr15-23.html\n    .iriUnicodeNormalization(Form.NFKC)\n    // set file directory for sources in mapping\n    .fileResolver(\"/some/dir/\")\n    // set classpath basepath for sources in mapping\n    .classPathResolver(\"some/path\")\n    // specify casing of hex numbers in IRI percent encoding (default = true)\n    // added for backwards compatibility with IRI encoding up until v0.2.3\n    .iriUpperCasePercentEncoding(false)\n    // Specify a custom value factory supplier\n    .valueFactorySupplier(ValidatingValueFactory::new)\n    //---------------\n\n    .build();\n\nModel result = mapper.mapToModel();\n```\n\nReactive Streams\n----------------\nCARML leverages [Project Reactor's](https://projectreactor.io/) implementation of\n[reactive streams](https://www.reactive-streams.org/) to achieve streaming and (potentially) non-blocking processing of\nmappings.\n\nCARML exposes Reactor's [Flux](https://projectreactor.io/docs/core/release/reference/#flux) data structure. When you\nexecute a RML mapping using one of the `Flux` returning methods you get a `Flux\u003cStatement\u003e` as result.\nThis allows for further processing with\n[the many reactive operators](https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html)\navailable for Flux.\n\n```java\nFlux\u003cStatement\u003e statements = mapper.map();\n// do some operations\nModel result = statements.collect(ModelCollector.toModel())\n    .block();\n```\n\nSupport for Apache Jena\n-------------------------\nAs CARML is built on [RDF4J](https://rdf4j.org/), the default output is either a\n[`Flux`](https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html) of RDF4J \n[`Statement`](https://rdf4j.org/javadoc/latest/org/eclipse/rdf4j/model/Statement.html)s, or an RDF4J \n[`Model`](https://rdf4j.org/javadoc/latest/org/eclipse/rdf4j/model/Model.html).\n\nHowever, CARML provides utilities to transform this output to equivalent Jena datastructures.\n\nTo use these utilities one needs to import the `io.carml.carml-converters-jena` dependency.\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.carml\u003c/groupId\u003e\n    \u003cartifactId\u003ecarml-converters-jena\u003c/artifactId\u003e\n    \u003cversion\u003e${carml.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nThe following example shows the streaming transformation of RDF Statements to Jena Quads and subsequent collection into\na Jena Dataset using the provided utilities.\n\n```java\nFlux\u003cStatement\u003e statements = mapper.map();\n\nDataset jenaDataset = statements.map(JenaConverters::toQuad)\n    .collect(JenaCollectors.toDataset());\n```\n\nInput stream extension\n---------------------\nWhen it comes to non-database sources, the current RML spec only supports the specification of file based sources in\nan `rml:LogicalSource`. However, it is often very useful to be able to transform stream sources.\n\nTo this end CARML introduces the notion of 'Named Streams'. Which follows the ontology\ndefined [here](https://github.com/carml/carml/tree/master/carml.ttl).\n\nSo now, you can define streams in your mapping like so:\n\n```\n:SomeLogicalSource\n  rml:source [\n    a carml:Stream ;\n    # NOTE: name is not mandatory and can be left unspecified, when working with a single stream\n    carml:streamName \"stream-A\" ;\n  ];\n  rml:referenceFormulation ql:JSONPath;\n  rml:iterator \"$\"\n.\n```\n\nThen the input stream can be mapped by providing a map of named input streams.\n\n```java\nRdfRmlMapper mapper = RdfRmlMapper.builder()\n    .triplesMaps(mapping)    \n    .setLogicalSourceResolver(Rdf.Ql.JsonPath, JsonPathResolver::getInstance)\n    .build();\n\nmapper.map(Map.of(\"stream-A\", inputStream));\n```\n\nNote that it is possible to map several input streams. When combining named input streams with an unnamed input stream, \nthe constant `RmlMapper.DEFAULT_STREAM_NAME` can be used as the name for the unnamed input stream. \n\n```java\nRdfRmlMapper mapper = RdfRmlMapper.builder()\n    .triplesMaps(mapping)\n    .setLogicalSourceResolver(Rdf.Ql.JsonPath, JsonPathResolver::getInstance)\n    .build();\n\nmapper.map(Map.of(\"stream-A\", inputStreamA, RmlMapper.DEFAULT_STREAM_NAME, defaultInputStream));\n```\n\nFunction extension\n------------------\nA recent development related to RML is the possibility of adding functions to the mix. This is a powerful extension that\nincreases the expressivity of mappings immensely. Do note that the function ontology is still under development at\nUGhent.\n\nBecause we believe that this extension can already be of great value, we've already adopted it in CARML.\n\n\u003c!--- TODO: explain that the function execution is a finisher, that is it runs the normal mapping, which creates the \nfunction execution triples, and the described execution is in turn evaluated and results in the term map value. ---\u003e\nThe way it works is, you describe the execution of a function in terms of the [Function Ontology (FnO)](https://fno.io/)\n.\n\nTake for example the SumFunction example of the [FnO spec](http://users.ugent.be/~bjdmeest/function/#complete-example).\nThis defines an instance `ex:sumFunction` of class `fno:Function` that is able to compute the sum of two values provided\nas parameters of the function at execution time.\n\nIt also describes an instance `ex:sumExecution` of `fno:execution`, which `fno:executes` `ex:sumFunction` which descibes\nan instance of an execution of the defined sum function. In this case with parameters 2 and 4.\n\nTo be able to use this in RML mappings we use executions of instances of `fno:Function` to determine the value of a term\nmap. The execution of a function can be seen as a post-processing step in the evaluation of a term map.\n\n```\n@prefix rr: \u003chttp://www.w3.org/ns/r2rml#\u003e .\n@prefix rml: \u003chttp://semweb.mmlab.be/ns/rml#\u003e .\n@prefix fnml: \u003chttp://semweb.mmlab.be/ns/fnml#\u003e .\n@prefix xsd: \u003chttp://www.w3.org/2001/XMLSchema#\u003e .\n@prefix fno: \u003chttps://w3id.org/function/ontology#\u003e .\n@prefix ex: \u003chttp://example.org/\u003e .\n\nex:sumValuePredicateObjectMap\n  rr:predicate ex:total ;\n  rr:objectMap [\n    a fnml:FunctionMap ;\n    fnml:functionValue [\n      rml:logicalSource ex:LogicalSource ;\n      rr:subjectMap [\n        rr:template \"functionExec\";\n        rr:termType rr:BlankNode ;\n        rr:class fno:Execution\n      ] ;\n      rr:predicateObjectMap\n        [\n          rr:predicate fno:executes ;\n          rr:objectMap [\n            rr:constant ex:sumFunction ;\n          ]\n        ] ,\n        [\n          rr:predicate ex:intParameterA ;\n          rr:objectMap [ rml:reference \"foo\" ]\n        ] ,\n        [\n          rr:predicate ex:intParameterB  ;\n          rr:objectMap [ rml:reference \"bar\" ]\n        ]\n    ] ;\n    rr:datatype xsd:integer ;\n  ]\n.\n```\n\nA function can be created in any `.java` class. The function should be annotated with `@FnoFunction`, providing the\nstring value of the function IRI, and the function parameters with `@FnoParam`, providing the string value of the\nfunction parameter IRIs.\n\n```java\npublic class RmlFunctions {\n\n  @FnoFunction(\"http://example.org/sumFunction\")\n  public int sumFunction(\n      @FnoParam(\"http://example.org/intParameterA\") int intA,\n      @FnoParam(\"http://example.org/intParameterB\") int intB\n  ) {\n    return intA + intB;\n  }\n\n}\n```\n\nThe class or classes containing the annotated functions can then be registered on the mapper via\nthe `RmlMapper#addFunctions` method.\n\n```java\nRdfRmlMapper mapper = RdfRmlMapper.builder()\n    .triplesMaps(mapping)\n    .setLogicalSourceResolver(Rdf.Ql.JsonPath, JsonPathResolver::getInstance)\n    .addFunctions(new YourRmlFunctions())\n    .build();\n\nModel result=mapper.mapToModel();\n```\n\nIt is recommended to describe and publish new functions in terms of FnO for interpretability of mappings, and, possibly,\nreuse of functions, but it's not mandatory for use in CARML.\n\nNote that it is currently possible to specify and use function executions as parameters of other function executions in\nCARML, although this is not (yet?) expressible in FnO.\n\nXML namespace extension\n-----------------------\n\nWhen working with XML documents, it is often necessary specify namespaces to identify a node's qualified name. Most\nXPath implementations allow you to register these namespaces, in order to be able to use them in executing XPath\nexpressions. In order to convey these expressions to the CARML engine, CARML introduces the class `carml:XmlDocument`\nthat can be used as a value of `rml:source`. An instance of  `carml:XmlDocument` can, if it is a file source, specify a\nlocation via the `carml:url` property, and specify namespace declarations via the `carml:declaresNamespace` property.\n\nFor example, given the following XML document:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cex:bookstore xmlns:ex=\"http://www.example.com/books/1.0/\"\u003e\n    \u003cex:book category=\"children\"\u003e\n        \u003cex:title lang=\"en\"\u003eHarry Potter\u003c/ex:title\u003e\n        \u003cex:author\u003eJ K. Rowling\u003c/ex:author\u003e\n        \u003cex:year\u003e2005\u003c/ex:year\u003e\n        \u003cex:price\u003e29.99\u003c/ex:price\u003e\n    \u003c/ex:book\u003e\n\u003c/ex:bookstore\u003e\n```\n\none can now use the following mapping, declaring namespaces, to use them in XPath expressions:\n\n```\n@prefix rr: \u003chttp://www.w3.org/ns/r2rml#\u003e.\n@prefix rml: \u003chttp://semweb.mmlab.be/ns/rml#\u003e.\n@prefix ql: \u003chttp://semweb.mmlab.be/ns/ql#\u003e .\n@prefix carml: \u003chttp://carml.taxonic.com/carml/\u003e .\n@prefix ex: \u003chttp://www.example.com/\u003e .\n\n\u003c#SubjectMapping\u003e a rr:TriplesMap ;\n  rml:logicalSource [\n    rml:source [\n      a carml:Stream ;\n      # or in case of a file source use:\n      # carml:url \"path-to-source\" ;\n      carml:declaresNamespace [\n        carml:namespacePrefix \"ex\" ;\n        carml:namespaceName \"http://www.example.com/books/1.0/\" ;\n      ] ;\n    ] ;\n    rml:referenceFormulation ql:XPath ;\n    rml:iterator \"/ex:bookstore/*\" ;\n  ] ;\n\n  rr:subjectMap [\n    rr:template \"http://www.example.com/{./ex:title}\" ;\n    rr:class ex:Book ;\n    rr:termType rr:IRI ;\n  ] ;\n.\n\n```\n\nwhich yields:\n\n```\n\u003chttp://www.example.com/Harry%20Potter\u003e a \u003chttp://www.example.com/Book\u003e .\n```\n\nCARML in RML Test Cases\n-----------------------\nSee the [RML implementation Report](https://rml.io/implementation-report/) for how CARML does in\nthe [RML test cases](https://rml.io/test-cases/).\n\n\u003e Note: currently we've raised [issues](https://github.com/RMLio/rml-test-cases/issues?q=is%3Aissue+author%3Apmaria+) \n\u003e for some of the test cases which we believe are incorrect, or have an adverse effect on mapping data.\n\nProjects using CARML\n--------------------\nThese projects are using CARML.\n\n* [carml-service](https://github.com/zazuko/carml-service/) - A project by [Zazuko](https://zazuko.com/) which creates a\n  web service around CARML. \n* [barnard59](https://github.com/zazuko/barnard59) - A project by [Zazuko](https://zazuko.com/) which provides a toolkit\n  to automate extract, transform and load (ETL) tasks. Its main focus is on creating Linked Data.\n* [DotWebStack](https://github.com/dotwebstack/dotwebstack-framework) - A Framework for publishing rich data services.\n  DotWebStack provides [an extension](https://dotwebstack.org/dotwebstack-framework/#/ext/rml) to provide support for \n  Linked data URI dereferencing, which uses CARML to transform data on the fly.\n\nAre you using CARML? Let us know, so we can add you to this list. Or better yet, open a PR.\n\nAbout CARML\n-----------\nCARML was first developed by [Taxonic](http://www.taxonic.com) in cooperation with [Kadaster](https://www.kadaster.com/)\n. And is now being maintained and developed further by [Skemu](https://skemu.com).\n","funding_links":[],"categories":["KGC Materializers","Mapping"],"sub_categories":["XML"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarml%2Fcarml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcarml%2Fcarml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarml%2Fcarml/lists"}