Add PureXML.XPath: a compiled location-path query engine reimplemented from the XPath 1.0 specification; no upstream code copied. - Compiler parses a path into steps; Evaluator walks the tree returning a Selection node-set (node or attribute) in document order. - Forward axes only (child, descendant //, self ., attribute @), since the value model has no parent pointers. Node tests: name, *, text(), node(), comment(). Predicates: [n], [@a], [@a='v'], [child], [child='v']. - Public surface: XPath.Query (init compiles, evaluate/elements/strings), the Selection enum (element / stringValue), QueryError, and the one-shot PureXML.xpath(_:over:). Upward/sibling axes and the full expression language are explicitly out of scope. - 12 XPath tests; 61 total.
18 lines
789 B
Swift
18 lines
789 B
Swift
extension PureXML.XPath {
|
|
/// A step predicate (`[...]`). A supported, practical subset: a position, an
|
|
/// attribute existence or equality test, or a child-element existence or
|
|
/// equality test.
|
|
enum Predicate: Equatable {
|
|
/// A one-based position, as in `book[1]`.
|
|
case position(Int)
|
|
/// `[@id]`: the context element has the named attribute.
|
|
case hasAttribute(String)
|
|
/// `[@id='x']`: the named attribute equals the value.
|
|
case attributeEquals(name: String, value: String)
|
|
/// `[title]`: the context element has a child element with the name.
|
|
case hasChild(String)
|
|
/// `[title='x']`: a child element with the name has the string value.
|
|
case childEquals(name: String, value: String)
|
|
}
|
|
}
|