CrystalXmlName
Namespace: SnowBank.Data.Xml · struct
Name of an XML element or attribute, held in both its text and UTF-8 representations, with an optional namespace
Remarks
The dual representation exists so that neither output core ever has to convert: the char core copies Text, the byte core copies Utf8. Names are written far more often than any other token in a document, so transcoding them at write time would dominate the cost.
Generated code emits one cached static readonly instance per name, built from a frozen UTF-8 literal so that no transcoding happens at all, not even once, via the public constructor below, which is the trusted, non-validating path: the generator already validated the literal at compile time, so re-validating it on every process start would be pure waste.
private static readonly CrystalXmlName TagsName = new("Tags", "Tags"u8.ToArray());
Use Create instead for names that are not known at compile time (a caller's rootName override, a dictionary key written under Direct). Unlike the constructor, Createvalidates that the name is a legal XML NCName and raises XmlException if it is not: this is the one place user-supplied text turns into a name, and a bad name must throw rather than corrupt the document.
Namespace is optional and defaults to None, so a name built the way it always was keeps meaning exactly what it did. A name holds the local name and the namespace and never a prefix: both of those are properties of the name itself, while the prefix depends on the depth of the element that declares the namespace and on what is in scope there, so the emitter assigns it. That is what keeps a name cacheable: one static instance serves every document and every depth.
Constructors
CrystalXmlName
CrystalXmlName(string text, ReadOnlyMemory<byte> utf8)
Constructs a name from its two representations
text— Text representation of the name, as written in the document by thecharcoreutf8— UTF-8 representation oftext, as written by thebytecore
The caller is responsible for the two representations agreeing: nothing checks that is the UTF-8 encoding of . Prefer unless you are emitting a frozen literal pair. The name gets no namespace, which is what every name of a document without namespaces is.
CrystalXmlName(string text, ReadOnlyMemory<byte> utf8, in CrystalXmlNamespace ns)
Constructs a name from its two representations
text— Text representation of the name, as written in the document by thecharcoreutf8— UTF-8 representation oftext, as written by thebytecore
The caller is responsible for the two representations agreeing: nothing checks that is the UTF-8 encoding of . Prefer unless you are emitting a frozen literal pair. The name gets no namespace, which is what every name of a document without namespaces is.
Properties
Namespace
CrystalXmlNamespace Namespace { get; }
Namespace of the name, or None when it has none
Text
string Text { get; }
Text representation of the local name, without any prefix
Utf8
ReadOnlySpan<byte> Utf8 { get; }
UTF-8 representation of the local name
Methods
Create
static CrystalXmlName Create(string text)
Builds a name from its text, validating it and computing the UTF-8 representation now
text— Text representation of the name
Returns: Name usable by both output cores
This transcodes, validates and allocates, so it belongs at setup time (a cached static, a rootName override), never on a per-element path. For a frozen literal already known to be valid at compile time, use the constructor instead: see the type remarks.
static CrystalXmlName Create(string text, string namespaceUri)
Builds a namespaced name, validating both halves and computing the UTF-8 representations now
text— Text representation of the LOCAL name, without any prefixnamespaceUri— Namespace URI, ornullfor no namespace
Returns: Name usable by both output cores
The two halves are validated by different rules, which is why they cannot share one check: the local name is an NCName and therefore carries no colon, while a namespace URI does (urn:acme:catalog:1). See for the namespace rule.
ToString
string ToString()