
Security News
GPT-6 Astra Attempts Supply Chain Attacks Against Open Source Maintainers in Testing
GPT-6 Astra hits 100% on ExploitBench and finds zero-days autonomously, while independent tests reveal scope violations and monitoring gaps.
Validates XML name productions — Name, NCName, QName, NMToken, NMTokens — for XML 1.0 and 1.1
Validates XML name productions as defined in the XML 1.0 and XML 1.1 specifications.
Covers all five productions:
| Production | Description | Colon | Digit/hyphen start |
|---|---|---|---|
Name | General XML name | ✅ | ❌ |
NCName | Non-Colonized name | ❌ | ❌ |
QName | Namespace-qualified name (prefix:local) | ✅ (one only) | ❌ |
NMToken | Name token (relaxed start) | ✅ | ✅ |
NMTokens | Whitespace-separated NMToken list | ✅ | ✅ |
Used internally by fast-xml-parser, fast-xml-validator, @nodable\flexible-xml-parser and fast-svg-parser.
npm install xml-naming
import { name, ncName, qName, nmToken, nmTokens } from 'xml-naming';
// Name — colon allowed anywhere, used for DOCTYPE entity names
name('foo') // true
name('a:b:c') // true ← multiple colons fine for Name
name('1foo') // false ← digit start invalid
// NCName — no colon, used for SVG id attributes, namespace prefixes
ncName('my-id') // true
ncName('xlink:href') // false ← colon not allowed
// QName — exactly one colon as prefix separator, used for element/attribute names
qName('svg:circle') // true
qName('foo') // true ← unprefixed QName is valid
qName('a:b:c') // false ← only one colon allowed
qName(':foo') // false ← cannot start with colon
// NMToken — any NameChar at start, used for DTD NMTOKEN attributes
nmToken('123') // true ← digit start is fine
nmToken('-bar') // true
nmToken('foo bar') // false ← space not allowed
// NMTokens — whitespace-separated NMToken list
nmTokens('tok1 tok2 -foo 123') // true
All validators accept an optional { xmlVersion } option:
import { name } from 'xml-naming';
name('\u0085', { xmlVersion: '1.0' }) // false — NEL (Next Line), not in 1.0 ranges
name('\u0085', { xmlVersion: '1.1' }) // true — explicitly allowed in 1.1
name('\uD800\uDC00', { xmlVersion: '1.0' }) // false
name('\uD800\uDC00', { xmlVersion: '1.1' }) // true
All validators, validate, validateAll, and sanitize also accept { asciiOnly: true }.
When set, matching is restricted to the ASCII subset of the NameStartChar/NameChar
productions and skips unicode-aware regex matching entirely — no \u00C0-\uFFFD-style
ranges, and (for XML 1.1) no /u regex flag. Unicode-aware regexes are measurably slower
than plain ASCII matching in JS engines, so this is a real performance win when you know
your input is ASCII-only, which is the common case for HTML/SVG ids and most XML tags.
This is opt-in and defaults to false for backward compatibility: turning it on
changes behavior, since it rejects legitimate non-ASCII XML names that would otherwise be
valid. Only enable it when you control the input and know it's ASCII (e.g. internal
identifiers, machine-generated names), not for validating arbitrary user- or
externally-supplied XML/SVG content.
import { name, sanitize } from 'xml-naming';
name('café', { asciiOnly: true }) // false — 'é' is not ASCII, even though it's
name('café') // true a valid XML 1.0/1.1 NameChar
sanitize('café', 'name', { asciiOnly: true }) // 'caf_' — non-ASCII replaced too
sanitize('café', 'name') // 'café' — left untouched by default
import { validate } from 'xml-naming';
validate('svg:circle', 'qName')
// { valid: true, production: 'qName', input: 'svg:circle' }
validate('1foo', 'ncName')
// {
// valid: false,
// production: 'ncName',
// input: '1foo',
// reason: 'First character "1" is not a valid NameStartChar',
// position: 0
// }
validate('foo:bar', 'ncName')
// {
// valid: false,
// production: 'ncName',
// input: 'foo:bar',
// reason: 'Colon is not allowed in NCName',
// position: 3
// }
validate('a:b:c', 'qName')
// {
// valid: false,
// production: 'qName',
// input: 'a:b:c',
// reason: 'QName can have at most one colon',
// position: 3
// }
import { validateAll } from 'xml-naming';
validateAll(['svg', 'circle', '123bad', 'xlink:href'], 'ncName')
// [
// { valid: true, production: 'ncName', input: 'svg' },
// { valid: true, production: 'ncName', input: 'circle' },
// { valid: false, production: 'ncName', input: '123bad', reason: '...', position: 0 },
// { valid: false, production: 'ncName', input: 'xlink:href',reason: '...', position: 5 }
// ]
Useful when generating XML/SVG programmatically from user-supplied strings:
import { sanitize } from 'xml-naming';
sanitize('123abc', 'ncName') // '_123abc' ← digit start fixed
sanitize('my element','name') // 'my_element' ← space replaced
sanitize('foo:bar', 'ncName') // 'foobar' ← colon stripped
sanitize('hello!', 'name') // 'hello_' ← illegal char replaced
// Custom replacement character
sanitize('my element', 'name', { replacement: '-' }) // 'my-element'
| Context | Production |
|---|---|
| XML element/attribute names (namespace-aware) | qName |
SVG id attribute values | ncName |
| Namespace prefix alone | ncName |
DOCTYPE <!ENTITY name ...> | name |
DOCTYPE <!NOTATION name ...> | name |
DTD NMTOKEN attribute values | nmToken |
DTD NMTOKENS attribute values | nmTokens |
Note: DOCTYPE entity and notation names must use
Name, notQName. Colons carry no namespace meaning in the DTD subset.
name(str, opts?) → booleanncName(str, opts?) → booleanqName(str, opts?) → booleannmToken(str, opts?) → booleannmTokens(str, opts?) → booleanopts:
xmlVersion: '1.0' (default) | '1.1'asciiOnly: boolean (default false) — ASCII-only fast path, see abovevalidate(str, production, opts?) → ValidationResultproduction: 'name' | 'ncName' | 'qName' | 'nmToken' | 'nmTokens'
opts: same as boolean validators (xmlVersion, asciiOnly)
validateAll(strings[], production, opts?) → ValidationResult[]opts: same as validate
sanitize(str, production?, opts?) → stringopts:
xmlVersion: '1.0' | '1.1'replacement: string (default '_')asciiOnly: boolean (default false) — also replaces non-ASCII characters, not just XML-illegal onesMIT
FAQs
Validates XML name productions — Name, NCName, QName, NMToken, NMTokens — for XML 1.0 and 1.1
The npm package xml-naming receives a total of 21,233,341 weekly downloads. As such, xml-naming popularity was classified as popular.
We found that xml-naming demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
GPT-6 Astra hits 100% on ExploitBench and finds zero-days autonomously, while independent tests reveal scope violations and monitoring gaps.

Product
Socket can now send alerts and supply chain attack notifications to Microsoft Teams, with filters that route the right updates to each channel.

Security News
pnpm 12 rewrites the package manager in Rust, cutting install times by up to 90% while preserving pnpm 11 workflows and lockfiles.