ddn.data.xml.xpath

XPath 1.0 engine.

This module provides XPath 1.0 expression parsing, evaluation, and value types with conversion rules.

Supported features:

  • All 13 XPath 1.0 axes except namespace (the DOM does not model namespace declarations as distinct nodes)
  • Node tests: name, ``, node(), text(), comment(), processing-instruction()
  • Predicates: numeric, boolean, and expression predicates
  • Full operator set: boolean (and, or), comparison (`=`, `!=`, `<`, `>`, `<=`, `>=`), arithmetic (`+`, `-`, ``, div, mod), union (`|`)
  • Core function library: last, position, count, id, string, concat, starts-with, contains, substring, substring-before, substring-after, string-length, normalize-space, translate, boolean, not, true, false, name, local-name, namespace-uri, number, sum, floor, ceiling, round, lang
  • Namespace-aware name matching via XPathNamespaceResolver

Remaining limitations:

  • The namespace axis is not supported (no DOM namespace-node type)
  • processing-instruction() literal argument (e.g. processing-instruction('xml-stylesheet')) is not supported
  • id() only matches elements with an unprefixed id attribute; DTD-declared ID-type attributes are not recognized
  • String functions operate on UTF-8 code units rather than Unicode code points; string-length() and substring() may produce incorrect results for multi-byte characters
  • Number formatting may use scientific notation for very large/small values

It is intentionally separate from the legacy/minimal ddn.data.xml.query module.

Types 16

XPath value kind.

NODESETNode-set value.
STRINGString value.
NUMBERNumber value (IEEE double).
BOOLEANBoolean value.

XPath axis.

All XPath 1.0 axes are defined except namespace, which is intentionally omitted because the DOM does not model namespace declarations as nodes.

CHILD`child::` axis.
DESCENDANT`descendant::` axis.
DESCENDANT_OR_SELF`descendant-or-self::` axis (`//`).
PARENT`parent::` axis (`..`).
SELF`self::` axis (`.`).
ATTRIBUTE`attribute::` axis (`@`).
ANCESTOR`ancestor::` axis.
ANCESTOR_OR_SELF`ancestor-or-self::` axis.
FOLLOWING_SIBLING`following-sibling::` axis.
PRECEDING_SIBLING`preceding-sibling::` axis.
FOLLOWING`following::` axis.
PRECEDING`preceding::` axis.

XPath node test kind.

NAMEMatch by name.
ANY`*` wildcard.
NODE`node()`
TEXT`text()`
COMMENT`comment()`
PROCESSING_INSTRUCTION`processing-instruction()`
private interfaceIXPathExpr
Methods
XPathValue evaluate(XmlNode context, XPathNamespaceResolver resolver, size_t position, size_t last) @safe
Fields
private XPathValue _val
Methods
XPathValue evaluate(XmlNode context, XPathNamespaceResolver resolver, size_t position, size_t last) @safe
Constructors
private classXPathPathExpr : IXPathExpr
Fields
private XPathExpression _path
Methods
XPathValue evaluate(XmlNode context, XPathNamespaceResolver resolver, size_t position, size_t last) @safe
Constructors
Fields
private IXPathExpr _expr
Methods
XPathValue evaluate(XmlNode context, XPathNamespaceResolver resolver, size_t position, size_t last) @safe
Constructors
private enumXPathBinaryOp
OR
AND
EQ
NEQ
LT
GT
LTE
GTE
PLUS
MINUS
MUL
DIV
MOD
UNION
Fields
private IXPathExpr _left
private XPathBinaryOp _op
Methods
XPathValue evaluate(XmlNode context, XPathNamespaceResolver resolver, size_t position, size_t last) @safe
Constructors
Fields
private string _name
private IXPathExpr[] _args
Methods
XPathValue evaluate(XmlNode context, XPathNamespaceResolver resolver, size_t position, size_t last) @safe
Constructors
this(string name, IXPathExpr[] args)
structXPathStep

A single path step.

Fields
string name
IXPathExpr[] predicates

A parsed XPath expression (subset).

Fields
string expressionOriginal expression string.
bool absoluteIf `true`, expression is absolute (starts with `/` or `//`).
private XPathStep[] _steps
Methods
XPathExpression parse(string expression) static @safeParses an XPath expression.
XmlNode[] select(XmlNode context, XPathNamespaceResolver resolver = null) @safeSelects nodes under `context`.
private structXPathParser
Fields
string s
size_t i
Methods
private IXPathExpr parseOrExpr() @safe
private IXPathExpr parseAndExpr() @safe
private IXPathExpr parseUnaryExpr() @safe
private IXPathExpr parseUnionExpr() @safe
private IXPathExpr parsePathExpr() @safe
private bool match(string op) @safe
private bool matchKeyword(string kw) @safe
private bool isNodeTest(string name) @safe pure nothrow

Namespace resolver for XPath evaluation.

Implementations map an XPath prefix to a namespace URI.

Methods
string lookupNamespaceUri(string prefix) @safe nothrow;Looks up a namespace URI for `prefix`.

Simple map-backed namespace resolver.

Fields
private string[string] _map
Methods
string lookupNamespaceUri(string prefix) @safe nothrow
Constructors
this(string[string] mappings)Constructs the resolver.

An XPath value (node-set, string, number, or boolean).

Fields
XPathValueKind kindValue kind discriminator.
private XmlNode[] _nodes
private string _string
private double _number
private bool _bool
Methods
XPathValue nodeset(XmlNode[] nodes) static @safeCreates a node-set value.
XPathValue string_(string value) static @safeCreates a string value.
XPathValue number(double value) static @safeCreates a number value.
XPathValue boolean(bool value) static @safeCreates a boolean value.
XmlNode[] toNodeSet() @safeReturns the value as a node-set.
bool toBoolean() const @safe nothrowConverts the value to a boolean using XPath 1.0 rules.
string toString() const @safeConverts the value to a string using XPath 1.0 rules.
double toNumber() const @safeConverts the value to a number using XPath 1.0 rules.

Functions 33

private fnXPathAxis axisFromName(string axisName) @safe
private fnbool isNameStartChar(char c) @safe pure nothrow
private fnbool isNameChar(char c) @safe pure nothrow
private fnbool compareValues(XPathValue l, XPathValue r, XPathBinaryOp op) @safe
fnXPathValue evaluateXPath(string expression, XmlNode context, XPathNamespaceResolver resolver = null) @safeEvaluates an XPath expression as an `XPathValue`.
private fnbool matchKeyword(string s, ref size_t i, string kw) @safe
private fnvoid parseInto(ref XPathExpression x, string s, ref size_t i) @safe
private fnvoid skipWs(string s, ref size_t i) @safe pure nothrow
private fnbool consumeCall(string s, ref size_t i) @safe pure nothrow
private fnstring readNameToken(string s, ref size_t i) @safe
private fnXmlNode rootOf(XmlNode n) @safe nothrow
private fnvoid collectDocumentOrder(ref XmlNode[] sink, XmlNode node) @safe
private fnbool isAncestorOf(XmlNode ancestor, XmlNode node) @safe nothrow
private fnsize_t indexOfNode(const(XmlNode)[] nodes, XmlNode target) @safe nothrow
private fnvoid appendAxisResults( ref XmlNode[] sink, XmlNode node, const ref XPathStep step, XPathNamespaceResolver resolver) @safe
private fnvoid appendDescendantsOrSelf( ref XmlNode[] sink, XmlNode node, const ref XPathStep step, XPathNamespaceResolver resolver) @safe
private fnbool matchesTest(XmlNode node, const ref XPathStep step, XPathNamespaceResolver resolver) @safe
private fnvoid splitQName(string qname, out string prefix, out string local) @safe nothrow
private fnXmlNode[] applyPredicates(XmlNode[] nodes, IXPathExpr[] preds, XPathNamespaceResolver resolver) @safe
private fnbool evaluatePredicate(IXPathExpr pred, XmlNode node, size_t position, size_t last, XPathNamespaceResolver resolver) @safe
private fnXPathValue evaluateFunctionExpr( string name, IXPathExpr[] args, XmlNode context, XPathNamespaceResolver resolver, size_t position, size_t last) @safe
private fnXmlNode[] dedupeInOrder(XmlNode[] nodes) @safe
private fnXmlNode[] sortInDocumentOrder(XmlNode[] nodes) @safe
private fnXmlNode[] dedupeInDocumentOrder(XmlNode[] nodes) @safe
private fnint compareDocumentOrder(XmlNode a, XmlNode b) @safe nothrow
private fnsize_t childIndex(const(XmlParentNode) p, const(XmlNode) child) @safe nothrow
private fnconst(void) * objectIdentityKey(Object o) @trusted nothrow
private fnstring nodesetStringValue(const(XmlNode)[] nodes) @safe
private fnstring nodeStringValue(const(XmlNode) node) @safe
private fnvoid collectDescendantText(ref typeof(appender!string()) sink, const(XmlParentNode) n) @safe
private fnstring formatXPathNumber(double v) @safe
private fnvoid collectIdTokens(string ids, ref bool[string] wanted) @safe pure nothrow
private fndouble parseXPathNumber(string s) @safe nothrow