PureXML/Sources/Emitting/Escaping.swift
Mihaela Mihaljevic 9b55767b39 feat(emitting): add an incremental XML writer (xmlTextWriter)
Add PureXML.Emitting.Writer, the libxml2 xmlTextWriter model: emit a document
with writeStartElement/writeAttribute/writeString/writeEndElement and friends,
never building a tree. Escaping is extracted into a shared Emitting.Escaping
helper used by both the writer and the serializer, so compact writer output is
byte-identical to serializing the equivalent tree. Pretty mode indents element
children (forward-only, so prefer compact for mixed content). Closes #32.
Reimplemented from the libxml2 model; no upstream code copied. 6 tests; 90 total.
2026-06-08 02:32:39 +02:00

39 lines
1.4 KiB
Swift

extension PureXML.Emitting {
/// The shared XML output escaping rules, used by both the tree serializer and
/// the incremental writer so their output is identical. Element content
/// escapes the markup characters; attribute values additionally escape the
/// quote and the whitespace characters as numeric references (matching
/// libxml2), so attributes survive attribute-value normalization.
enum Escaping {
static func text(_ value: String) -> String {
var result = ""
for character in value {
switch character {
case "&": result += "&"
case "<": result += "&lt;"
case ">": result += "&gt;"
default: result.append(character)
}
}
return result
}
static func attribute(_ value: String) -> String {
var result = ""
for character in value {
switch character {
case "&": result += "&amp;"
case "<": result += "&lt;"
case ">": result += "&gt;"
case "\"": result += "&quot;"
case "\t": result += "&#9;"
case "\n": result += "&#10;"
case "\r": result += "&#13;"
default: result.append(character)
}
}
return result
}
}
}