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 (phased):
XPathValue,XPathValueKind(ddn.data.xml.xpath)- XPointer (phased):
XPointer(ddn.data.xml.xpointer)- XInclude (phased):
processXInclude,XmlXIncludeOptions(ddn.data.xml.xinclude)- RelaxNG (native, phased):
parseRelaxNg,validateRelaxNgDocument(ddn.data.xml.relaxng)- XSD (native, phased):
parseXsd,validateXsdDocument(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.
- Richer querying surface area (more XPath features).
- 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("t"); 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></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\"/>") ); ---