fix(xml): accept the element names XML actually allows - #564
Merged
Conversation
`writeXml` turns a column heading into an element name and validated it
with
/^[A-Za-z_][\w.-]*(?::[A-Za-z_][\w.-]*)?$/
which is ASCII. XML 1.0 §2.3's `NameStartChar` runs from #xC0, so every
accented or non-Latin heading was refused:
writeXml([{ Şehir: "İzmir" }])
ParseError: Invalid XML name for element "Şehir": "Şehir"
`Şehir`, `Ünvan`, `Größe`, `café`, `naïve`, `名前`, `Ελλάδα`,
`Кириллица` — all valid XML, all rejected. A spreadsheet whose columns
are not named in English could not be written to XML **at all**. Not
mangled, not escaped: the format was unavailable, and the error said the
name was invalid when it was the check that was.
Found while testing #563, where a Turkish sheet could go to CSV, TSV,
JSON, NDJSON, HTML and Markdown but not XML.
## The productions, minus the colon
`NameStartChar` and `NameChar` verbatim, with `:` pulled out so a name
may carry one prefix rather than a colon wherever it likes — that is
`QName` from Namespaces in XML §4, and it is what the old regex was
reaching for too.
The `u` flag is not optional here: #x10000–#xEFFFF is above the BMP, and
without it the surrogate halves match separately.
Nothing new is accepted that XML forbids. A leading digit, a leading
hyphen or dot, a space, `<`, two colons, the empty string, and a leading
combining mark — `NameChar` but not `NameStartChar` — are still refused,
each with a test.
## Checked
27 tests, **14 of which fail against the old regex** and none of which is
a rejection case: the tests that say what stays refused pass either way,
which is the point of having them.
The reader was never the problem — `parseXml` reads any well-formed name
— and a non-ASCII name now round-trips through both.
`pnpm test` green — 10,622 tests, 236 files.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
productdevbook
force-pushed
the
fix/xml-names
branch
from
August 13, 2026 17:19
037db01 to
d2f86e7
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fix(xml): accept the element names XML actually allows
writeXmlturns a column heading into an element name and validated itwith
which is ASCII. XML 1.0 §2.3's
NameStartCharruns from #xC0, so everyaccented or non-Latin heading was refused:
Şehir,Ünvan,Größe,café,naïve,名前,Ελλάδα,Кириллица— all valid XML, all rejected. A spreadsheet whose columnsare not named in English could not be written to XML at all. Not
mangled, not escaped: the format was unavailable, and the error said the
name was invalid when it was the check that was.
Found while testing #563, where a Turkish sheet could go to CSV, TSV,
JSON, NDJSON, HTML and Markdown but not XML.
The productions, minus the colon
NameStartCharandNameCharverbatim, with:pulled out so a namemay carry one prefix rather than a colon wherever it likes — that is
QNamefrom Namespaces in XML §4, and it is what the old regex wasreaching for too.
The
uflag is not optional here: #x10000–#xEFFFF is above the BMP, andwithout it the surrogate halves match separately.
Nothing new is accepted that XML forbids. A leading digit, a leading
hyphen or dot, a space,
<, two colons, the empty string, and a leadingcombining mark —
NameCharbut notNameStartChar— are still refused,each with a test.
Checked
27 tests, 14 of which fail against the old regex and none of which is
a rejection case: the tests that say what stays refused pass either way,
which is the point of having them.
The reader was never the problem —
parseXmlreads any well-formed name— and a non-ASCII name now round-trips through both.
pnpm testgreen — 10,622 tests, 236 files.Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
🤖 Generated with Claude Code