Merge MVP features #1

Merged
dominic merged 16 commits from prototype into master 2026-04-24 18:48:16 +00:00
Owner

This PR introduces the complete initial implementation of XNeedle,
a fault injection tool for XML documents, primarily targeting EtherCAT
SubDevice Information (ESI) files.

Parser

  • Implemented the XNeedle .xn DSL parser using Sprache
  • RuleObject — XPath-selected node blocks: $("//xpath") { ... }
  • BangObject — named operations with arguments: !add("Tag") { ... }
  • ExpressionPart — arithmetic, string concat, and function call expressions
  • # single-line comment support via preprocessing (quote-aware, preserves line numbers)
  • Friendly parse error reporting with filename, line and column

Transformation

  • Rule — applies a block of operations to all XPath-matched nodes
  • Bang — dispatches to a registered BangOperation by name
  • BangOperation registry with automatic discovery via reflection

Built-in Bang Operations

  • !add(tag) — add a child element, body operates on new node
  • !before(tag) — insert a sibling element before the current node

Built-in Context Functions

  • text() / text(value) — get/set element text content
  • cdata() / cdata(value) — get/set CDATA section
  • attr(name) / attr(name, value) — get/set attributes
  • rename(newName) / rename(select, newName) — rename elements or attributes
  • remove(select) — remove matched nodes
  • crc() — calculate CRC32 of the current node's subtree
  • hex(value) — format a number as uppercase hex string

Tooling

  • Single-binary publish configured for linux-x64 as xn
  • CLI interface: xn <file.xn> -i input.xml -o output.xml
This PR introduces the complete initial implementation of XNeedle, a fault injection tool for XML documents, primarily targeting EtherCAT SubDevice Information (ESI) files. ### Parser - Implemented the XNeedle `.xn` DSL parser using Sprache - `RuleObject` — XPath-selected node blocks: `$("//xpath") { ... }` - `BangObject` — named operations with arguments: `!add("Tag") { ... }` - `ExpressionPart` — arithmetic, string concat, and function call expressions - `#` single-line comment support via preprocessing (quote-aware, preserves line numbers) - Friendly parse error reporting with filename, line and column ### Transformation - `Rule` — applies a block of operations to all XPath-matched nodes - `Bang` — dispatches to a registered `BangOperation` by name - `BangOperation` registry with automatic discovery via reflection ### Built-in Bang Operations - `!add(tag)` — add a child element, body operates on new node - `!before(tag)` — insert a sibling element before the current node ### Built-in Context Functions - `text()` / `text(value)` — get/set element text content - `cdata()` / `cdata(value)` — get/set CDATA section - `attr(name)` / `attr(name, value)` — get/set attributes - `rename(newName)` / `rename(select, newName)` — rename elements or attributes - `remove(select)` — remove matched nodes - `crc()` — calculate CRC32 of the current node's subtree - `hex(value)` — format a number as uppercase hex string ### Tooling - Single-binary publish configured for `linux-x64` as `xn` - CLI interface: `xn <file.xn> -i input.xml -o output.xml`
dominic added 16 commits 2026-04-24 18:45:57 +00:00
- Thread runtime Context through expression trees via ParameterExpression
  instead of baking a parse-time constant (Node was always null)
- Fix ExpressionPart to compile Func<Context,string> and invoke with live ctx
- Coerce double arithmetic expressions to string before lambda wrapping
- Remove HasAttributes guard in attr() that blocked new attribute creation
- Replace GetLevel(XmlNode) with XElement.Parent-based implementation
- Add cdata()/cdata(txt) functions to read/write CDATA nodes in place,
  preserving the XCData wrapper that SetValue() would destroy

Clanker: claude-sonnet_4.6
Clanker: claude-sonnet_4.6
- Add SourceLocation struct (XNeedle namespace) with FilePath, Encoding,
  and LineNumber (-1 sentinel when unavailable)
- Add SLoc property to Context; Clone() propagates it for free
- Expose XmlRoundtripWriter.DetectEncoding as internal static
- Add XmlRoundtripWriter.CreateToString(filePath, encoding) returning a
  (writer, StringBuilder) tuple for in-memory style-preserving rendering
- Update XmlFragParser.ChecksumData to accept tagName only; use
  OpeningTagAnchor to skip the opening tag robustly, and AnyChar.Until()
  to non-greedily capture content through the closing tag
- Thread SourceLocation from Program.cs through Rule.Transform/Operate,
  refreshing LineNumber per node via IXmlLineInfo
- Implement ContextFunctions.crc: render node via CreateToString, extract
  digest slice via ChecksumData, encode with SLoc.Encoding, return CRC32
  as double for arithmetic compatibility

Clanker: claude-sonnet_4.6
One minor bug found after claude review.

Clanker: claude-sonnet_4.6
Clanker: claude-sonnet_v4.6
dominic merged commit ce614c0547 into master 2026-04-24 18:48:16 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dominic/xn#1
No description provided.