From 26649e5c73c893af893b124993592a87b30cd257 Mon Sep 17 00:00:00 2001 From: Mihaela Mihaljevic Date: Mon, 8 Jun 2026 15:01:48 +0200 Subject: [PATCH] feat(parsing): xmlReader breadth: attribute navigation, namespaces, lang, position Broaden the TextReader pull cursor toward libxml2's xmlTextReader: - Attribute nodes: moveToFirstAttribute/moveToNextAttribute/ moveToAttribute(_:)/moveToElement reposition the cursor onto each attribute as an .attribute node and back. - Namespace accessors: namespaceURI, localName, prefix from the current element's or attribute's resolved name. - xml:lang: inherited down the tree, overridable per element, reset when it goes out of scope. - Position: lineNumber/columnNumber report where each node begins, so a streaming consumer can locate findings in the source. EventReader now records each node's start mark. DOCTYPE and entity-reference nodes are not surfaced (the DTD is exposed through documentType, and entities are expanded inline); whitespace is not split into significant/insignificant (needs the content model); baseURI needs a document URI. The accurate positioning path for editor findings remains readTree with source ranges. Closes #98 --- Sources/Parsing/EventReader.swift | 5 ++ Sources/Parsing/TextReader.swift | 120 ++++++++++++++++++++++++++++- Tests/TextReaderBreadthTests.swift | 92 ++++++++++++++++++++++ 3 files changed, 213 insertions(+), 4 deletions(-) create mode 100644 Tests/TextReaderBreadthTests.swift diff --git a/Sources/Parsing/EventReader.swift b/Sources/Parsing/EventReader.swift index 05d1aa8..62fd106 100644 --- a/Sources/Parsing/EventReader.swift +++ b/Sources/Parsing/EventReader.swift @@ -34,6 +34,9 @@ public extension PureXML.Parsing { var reachedEnd = false /// The problems found so far, when reading in recovering mode. var diagnostics: [Diagnostic] = [] + /// The source position where the most recently produced event's node began, + /// so a pull cursor can report each node's line and column. + private(set) var eventStart: Mark = .start /// Creates a reader over a character-pulling source. The closure returns /// the next character or nil at end of input. @@ -94,6 +97,7 @@ public extension PureXML.Parsing { guard let lead = reader.peek() else { return nil } + eventStart = reader.mark if reader.matches("