ddn.data.xml
ddn.data.xml is an idiomatic XML library for the D programming language.
This umbrella module is intended as the primary import for users. The public API is split into focused entrypoints (e.g. ddn.data.xml.parse, ddn.data.xml.dom, ddn.data.xml.write). This module re-exports the commonly used parts.
Public surface (v1)
The initial v1 public API is defined by the stable entrypoint modules below.
Currently available (implemented in this repository):
- DOM:
XmlDocument,XmlElement,XmlNodeand core node types (ddn.data.xml.dom)- Parsing:
parseDocument,parseFragment,XmlParseOptions(ddn.data.xml.parse)- Serialization:
writeXml,toXmlString,writeXmlTo,XmlWriteOptions(ddn.data.xml.write)- Streaming:
XmlReader,XmlEvent,XmlEventType(ddn.data.xml.stream)- Streaming (incremental):
XmlIncrementalReader,XmlIncrementalReaderOptions,XmlStreamStatus(ddn.data.xml.stream)- SAX (push parsing):
XmlSaxHandler,parseSax,XmlSaxOptions(ddn.data.xml.sax)- SAX (incremental):
XmlIncrementalSaxParser(ddn.data.xml.sax)- Querying:
XmlPath(ddn.data.xml.query)- XPath:
XPathValue,XPathValueKind,XPathExpression,evaluateXPath(ddn.data.xml.xpath)- XPointer:
XPointer,XPointerPart,XPointerKind(ddn.data.xml.xpointer)- XInclude:
processXInclude,XmlXIncludeOptions(ddn.data.xml.xinclude)- RelaxNG:
parseRelaxNg,validateRelaxNgDocument(ddn.data.xml.relaxng)- XSD (native):
parseXsd,parseXsdFromFile,validateXsdDocument,XsdSchema,XsdParseOptions(ddn.data.xml.xsd)- Validation (CLI-backed for now):
validateXsdFile,validateRelaxNgFile(ddn.data.xml.validate)- Canonicalization:
canonicalize(ddn.data.xml.c14n)
Planned (to be implemented/expanded in subsequent tasks, keeping these names stable):
- Full XML 1.0 name/character support (beyond the current ASCII-focused subset).
- Full entity and DTD parsing (internal/external subsets), with robust safety limits.
- XPath
namespaceaxis andprocessing-instruction()literal argument support. - Additional validation modes (DTD validation, richer schema APIs, non-CLI implementations).
Stability rules
- Stable modules:
ddn.data.xmland the public entrypoints it re-exports.ddn.data.xml.dom.*.- Unstable modules (not part of the public API):
ddn.data.xml.internal.*.- Test helpers (package-only by convention):
ddn.data.xml.testing.*.
Examples
Parse a document
import ddn.data.xml.parse : parseDocument;
auto doc = parseDocument("<root><child>t</child></root>");
assert(doc.documentElement.lexicalName == "root");Build a document (DOM)
import ddn.data.xml.dom.document : XmlDocument;
auto doc = new XmlDocument();
auto root = doc.createRootElement("root");
root.addChildElement("child").withAttribute("id", "1").addText("t");Serialize a document
import ddn.data.xml.write : writeXml;
string xml = writeXml(doc);#### Streaming reader (pull)
import ddn.data.xml.stream : XmlEventType, XmlReader;
auto r = new XmlReader("<a><b/>t</a>");
while (!r.empty)
{
// Consume events.
if (r.front.type == XmlEventType.TEXT)
assert(r.front.text == "t");
r.popFront();
}#### Incremental streaming reader (chunked input)
import ddn.data.xml.stream : XmlIncrementalReader, XmlStreamStatus,
XmlEventType;
auto reader = new XmlIncrementalReader();
reader.feed("<root><child/>");
reader.feed("</root>");
reader.markEndOfStream();
while (reader.advance() == XmlStreamStatus.READY)
{
if (reader.front().type == XmlEventType.START_ELEMENT)
import std.stdio : writeln;
// process reader.front() ...
}#### Incremental SAX (chunked input)
import ddn.data.xml.sax : XmlSaxHandler, XmlIncrementalSaxParser,
XmlSaxOptions, XmlSaxAttribute;
import ddn.data.xml.stream : XmlStreamStatus;
import ddn.data.xml.errors : XmlLocation;
class MyHandler : XmlSaxHandler {
override void startElement(string name,
const(XmlSaxAttribute)[] attrs, XmlLocation loc) @safe { }
override void endElement(string name, XmlLocation loc) @safe { }
override void text(string value, XmlLocation loc) @safe { }
override void comment(string value, XmlLocation loc) @safe { }
override void processingInstruction(string target,
string data, XmlLocation loc) @safe { }
override void cdata(string value, XmlLocation loc) @safe { }
override void doctype(string raw, XmlLocation loc) @safe { }
}
auto parser = new XmlIncrementalSaxParser(new MyHandler());
parser.feed("<root><child/></root>");
parser.markEndOfStream();
parser.pump();Query elements (XPath-like)
import ddn.data.xml.query : XmlPath;
import ddn.data.xml.parse : parseDocument;
auto doc = parseDocument("<root><a/><a id='2'/></root>");
auto path = XmlPath.parse("a[@id='2']");
auto result = path.select(doc.documentElement);
assert(result.length == 1);Canonicalize for stable comparisons
import ddn.data.xml.c14n : canonicalize;
import ddn.data.xml.parse : parseDocument;
auto doc = parseDocument("<root b='2' a='1'/>" );
assert(canonicalize(doc).canFind("<root a=\"1\" b=\"2\"/>") );No exported symbols.