RDF/XML

W3C-compliant RDF/XML parsing and serialization.
Full-featured, high-performance, and easy to use.

The Challenge

RDF/XML is one of the most widely used RDF serialization formats, but it's also one of the most complex to parse and generate correctly.

Complex Syntax

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:dc="http://purl.org/dc/elements/1.1/">
  <rdf:Description rdf:about="http://example.org/book">
    <dc:title>The Semantic Web</dc:title>
    <dc:creator>Tim Berners-Lee</dc:creator>
  </rdf:Description>
</rdf:RDF>

Many Features

  • Typed node elements
  • Property elements
  • Containers (Bag, Seq, Alt)
  • Collections (rdf:List)
  • parseType variations
  • XML Base support
  • Language tags
  • Blank nodes

You need a robust, standards-compliant implementation. Parsing and generating RDF/XML correctly requires:

  • Complete W3C RDF/XML specification support
  • Proper handling of all RDF/XML syntax variations
  • Efficient XML processing
  • Configurable behavior for different use cases

The Solution

A complete, W3C-compliant RDF/XML implementation that handles all the complexity for you.

Simple API, Powerful Features

import 'package:locorda_rdf_xml/locorda_rdf_xml.dart';

// Decode RDF/XML to a graph
final graph = rdfxml.decode(xmlContent);

// Encode a graph to RDF/XML
final xml = rdfxml.encode(graph);

βœ“ One-line decoding and encoding
βœ“ Full W3C RDF/XML specification support
βœ“ Configurable for your needs

Getting Started

Install the package

dart pub add locorda_rdf_xml locorda_rdf_core
// Quick start example for RDF/XML parsing and serialization
import 'package:locorda_rdf_xml/xml.dart';

void main() {
  // Example RDF/XML document
  final xmlContent = '''
    <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
             xmlns:dc="http://purl.org/dc/elements/1.1/">
      <rdf:Description rdf:about="http://example.org/book">
        <dc:title>The Semantic Web</dc:title>
        <dc:creator>Tim Berners-Lee</dc:creator>
      </rdf:Description>
    </rdf:RDF>
  ''';

  // Decode RDF/XML to a graph
  final graph = rdfxml.decode(xmlContent);

  print('Parsed ${graph.size} triples:');
  for (final triple in graph.triples) {
    print('  $triple');
  }

  // Encode the graph back to RDF/XML
  final encoded = rdfxml.encode(graph);
  print('\nEncoded RDF/XML:\n$encoded');
}
// Integration with RdfCore for multi-format support
import 'package:locorda_rdf_core/core.dart';
import 'package:locorda_rdf_xml/xml.dart';

void main() {
  // Register RDF/XML codec with RdfCore
  final rdfCore = RdfCore.withStandardCodecs(
    additionalCodecs: [RdfXmlCodec()],
  );

  final xmlContent = '''
    <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
             xmlns:foaf="http://xmlns.com/foaf/0.1/">
      <foaf:Person rdf:about="http://example.org/alice">
        <foaf:name>Alice</foaf:name>
        <foaf:knows>
          <foaf:Person>
            <foaf:name>Bob</foaf:name>
          </foaf:Person>
        </foaf:knows>
      </foaf:Person>
    </rdf:RDF>
  ''';

  // Decode from RDF/XML
  final graph = rdfCore.decode(
    xmlContent,
    contentType: 'application/rdf+xml',
  );

  print('Decoded ${graph.size} triples');

  // Convert to Turtle format
  final turtle = rdfCore.encode(graph, contentType: 'text/turtle');
  print('\nAs Turtle:\n$turtle');

  // Convert to N-Triples format
  final ntriples = rdfCore.encode(graph, contentType: 'application/n-triples');
  print('\nAs N-Triples:\n$ntriples');
}
// Configuration options for RDF/XML encoding and decoding
import 'package:locorda_rdf_core/core.dart';
import 'package:locorda_rdf_xml/xml.dart';

void main() {
  final graph = RdfGraph.fromTriples([
    Triple(
      const IriTerm('http://example.org/resource'),
      const IriTerm('http://purl.org/dc/elements/1.1/title'),
      LiteralTerm.string('Example Resource'),
    ),
  ]);

  // Readable output with pretty printing
  print('=== READABLE (pretty-printed) ===');
  final readable = RdfXmlCodec.readable().encode(graph);
  print(readable);

  // Compact output for minimal size
  print('\n=== COMPACT (minimal whitespace) ===');
  final compact = RdfXmlCodec.compact().encode(graph);
  print(compact);

  // Custom configuration
  print('\n=== CUSTOM CONFIGURATION ===');
  final custom = RdfXmlCodec(
    encoderOptions: RdfXmlEncoderOptions(
      prettyPrint: true,
      indentSpaces: 2,
      useTypedNodes: true,
      customPrefixes: {
        'dcelems': 'http://purl.org/dc/elements/1.1/',
        'ex': 'http://example.org/',
      },
    ),
  ).encode(graph);
  print(custom);

  // Strict vs lenient parsing
  print('\n=== PARSING MODES ===');
  print('Strict mode: validates strictly against W3C spec');
  print('Lenient mode: tolerates common RDF/XML variations');
  print('Use RdfXmlCodec.strict() or RdfXmlCodec.lenient() to create codecs');
}
// Base URI handling for relative URIs in RDF/XML
import 'package:locorda_rdf_core/core.dart';
import 'package:locorda_rdf_xml/xml.dart';

void main() {
  final graph = RdfGraph.fromTriples([
    Triple(
      const IriTerm('http://example.org/docs/document'),
      const IriTerm('http://purl.org/dc/elements/1.1/title'),
      LiteralTerm.string('My Document'),
    ),
    Triple(
      const IriTerm('http://example.org/docs/images/photo.jpg'),
      const IriTerm('http://purl.org/dc/elements/1.1/title'),
      LiteralTerm.string('Photo'),
    ),
  ]);

  final baseUri = 'http://example.org/docs/';

  // Scenario 1: With base URI - URIs are relativized AND xml:base is included
  // Output: xml:base="http://example.org/docs/" rdf:about="document"
  print('=== SCENARIO 1: With baseUri + xml:base declaration (default) ===');
  final withBase = rdfxml.encode(graph, baseUri: baseUri);
  print(withBase);

  // Scenario 2: With base URI but no declaration - URIs are relativized but xml:base is omitted
  // Output: (no xml:base) rdf:about="document"
  // ⚠️ WARNING: Parsing such documents requires providing documentUrl to resolve relative URIs!
  print('\n=== SCENARIO 2: With baseUri but WITHOUT xml:base declaration ===');
  final withoutBase = RdfXmlCodec(
    encoderOptions: RdfXmlEncoderOptions(
      includeBaseDeclaration: false,
    ),
  ).encode(graph, baseUri: baseUri);
  print(withoutBase);

  // Scenario 3: Without base URI - all URIs remain absolute
  // Output: (no xml:base) rdf:about="http://example.org/docs/document"
  print('\n=== SCENARIO 3: WITHOUT baseUri (absolute URIs) ===');
  final withoutBaseUri = rdfxml.encode(graph); // No baseUri parameter
  print(withoutBaseUri);

  // Parsing with base URI
  print('\n=== PARSING: Relative URIs with xml:base ===');
  final xmlWithRelative = '''
    <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
             xmlns:dc="http://purl.org/dc/elements/1.1/"
             xml:base="http://example.org/docs/">
      <rdf:Description rdf:about="document">
        <dc:title>Relative URI Example</dc:title>
      </rdf:Description>
    </rdf:RDF>
  ''';

  final parsed = rdfxml.decode(xmlWithRelative);
  print('Parsed ${parsed.size} triple(s):');
  for (final triple in parsed.triples) {
    print('  $triple');
  }
}
// XML Entities support in RDF/XML
import 'package:locorda_rdf_xml/xml.dart';

void main() {
  // RDF/XML with DOCTYPE entity declarations
  final xmlWithEntities = '''
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rdf:RDF [
    <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
    <!ENTITY lcc-cr "https://www.omg.org/spec/LCC/Countries/CountryRepresentation/" >
    <!ENTITY owl "http://www.w3.org/2002/07/owl#" >
    <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
    <!ENTITY skos "http://www.w3.org/2004/02/skos/core#" >
]>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:owl="&owl;"
         xmlns:rdfs="&rdfs;"
         xmlns:skos="&skos;">
  <owl:ObjectProperty rdf:about="&lcc-cr;classifies">
    <rdfs:label>classifies</rdfs:label>
    <skos:definition rdf:datatype="&xsd;string">arranges in categories according to shared characteristics</skos:definition>
    <rdfs:isDefinedBy rdf:resource="&lcc-cr;" />
  </owl:ObjectProperty>
</rdf:RDF>
  ''';

  print('=== PARSING RDF/XML WITH XML ENTITIES ===\n');

  // Parse the RDF/XML with entities
  final graph = rdfxml.decode(xmlWithEntities);

  print('Parsed ${graph.size} triples:\n');
  for (final triple in graph.triples) {
    print('  $triple');
  }

  print('\n=== ENTITY EXPANSION ===');
  print('Entities like &xsd; and &lcc-cr; are automatically expanded');
  print('to their full URIs during parsing.');
  print('\nExample:');
  print('  &xsd;string β†’ http://www.w3.org/2001/XMLSchema#string');
  print(
      '  &lcc-cr;classifies β†’ https://www.omg.org/spec/LCC/Countries/CountryRepresentation/classifies');

  print('\n⚠️ Note: XML entities are supported for PARSING only.');
  print('When encoding RDF to XML, full URIs are used (no entity references).');
}

Use Cases

πŸ“š Legacy Data Integration

Parse RDF/XML from existing systems and databases. Many legacy semantic web applications use RDF/XML as their primary format.

🌐 Web Services

Consume and produce RDF/XML APIs. Many semantic web services and SPARQL endpoints return results in RDF/XML format.

πŸ“„ Document Processing

Extract metadata from RDF/XML documents. Process Dublin Core, FOAF, and other vocabularies embedded in XML documents.

πŸ”„ Format Conversion

Convert between RDF serialization formats. Parse RDF/XML and serialize to Turtle, JSON-LD, or N-Triples.

πŸ“Š Data Publishing

Publish semantic data in RDF/XML format. Generate well-formed, readable RDF/XML for documentation and data exchange.

πŸ§ͺ Testing & Validation

Validate RDF/XML documents against the W3C specification. Test your RDF data processing pipelines with strict or lenient modes.

Key Features

βœ… Complete W3C Support

Full implementation of the W3C RDF/XML specification. All syntax features including typed nodes, containers, collections, and parseType variations.

⚑ High Performance

Optimized for both speed and memory efficiency. Fast XML parsing with efficient RDF graph construction.

πŸŽ›οΈ Configurable Behavior

Choose between strict W3C compliance or lenient parsing. Control formatting, indentation, and namespace prefixes.

πŸ”— Seamless Integration

Works perfectly with locorda_rdf_core. Register as a codec to enable automatic RDF/XML support across your application.

🎨 Pretty Printing

Generate human-readable RDF/XML with configurable indentation. Perfect for documentation and debugging.

🌍 Base URI Support

Full support for xml:base attributes and relative URI resolution. Control base URI declaration in output.

🏷️ Custom Prefixes

Define custom namespace prefixes for cleaner output. Automatic prefix generation for unknown namespaces.

πŸ§ͺ Well Tested

Comprehensive test suite with real-world examples. Tested against W3C test cases and production RDF/XML documents.

Core API

rdfxml.decode()

Parse RDF/XML string to RdfGraph

final graph = rdfxml.decode(xmlContent);

rdfxml.encode()

Serialize RdfGraph to RDF/XML string

final xml = rdfxml.encode(graph);

RdfXmlCodec.strict()

Create codec with strict W3C validation

final codec = RdfXmlCodec.strict();
final graph = codec.decode(xml);

RdfXmlCodec.lenient()

Create codec that tolerates variations

final codec = RdfXmlCodec.lenient();
final graph = codec.decode(xml);

RdfXmlCodec.readable()

Create codec for pretty-printed output

final codec = RdfXmlCodec.readable();
final xml = codec.encode(graph);

RdfXmlCodec.compact()

Create codec for minimal output size

final codec = RdfXmlCodec.compact();
final xml = codec.encode(graph);

RDF/XML Features Supported

βœ“

Resource Descriptions

rdf:Description elements

βœ“

Typed Node Elements

Custom element types

βœ“

Property Elements

All property variations

βœ“

Containers

rdf:Bag, rdf:Seq, rdf:Alt

βœ“

Collections

rdf:List with parseType

βœ“

parseType Variations

Resource, Literal, Collection

βœ“

XML Base

xml:base attribute support

βœ“

Language Tags

xml:lang attribute support

βœ“

Datatyped Literals

rdf:datatype attribute

βœ“

Blank Nodes

Anonymous and labeled

βœ“

RDF Reification

Statement reification

βœ“

Namespace Prefixes

Custom and automatic

βœ“

XML Entities (Parsing)

DOCTYPE entity declarations

Ready to Parse RDF/XML?

Start using W3C-compliant RDF/XML in your Dart projects today.