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-namingimport { 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') // trueAll 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' }) // trueimport { 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.
opts:
xmlVersion:'1.0'(default) |'1.1'
production: 'name' | 'ncName' | 'qName' | 'nmToken' | 'nmTokens'
opts:
xmlVersion:'1.0'|'1.1'replacement: string (default'_')
MIT