# sniff-xml-decl ## Purpose Extracts the declared encoding from an XML or SVG document's processing instruction (``). XML documents commonly declare their encoding in the prolog, and this declaration must be trusted before any BOM or HTTP header when present, per the XML specification (RFC 7303). ## Features - Matches the `encoding` attribute in `` declarations - Supports both double-quoted and single-quoted attribute values - Case-insensitive matching — `ENCODING` and `encoding` both match - Scans only the first 256 characters (the XML prolog is always at the start) - Returns the encoding name in lowercase for canonical comparison - Returns `null` when no XML declaration or encoding attribute is found - Handles whitespace variations between attributes ## Usage: Basic Example ```typescript import { sniffXmlDecl } from "@suaveplan/mime/charset/sniff-xml-decl"; const xml = ''; const encoding = sniffXmlDecl(xml); console.log(encoding); // "utf-8" ``` ## Usage: Advanced Example ```typescript import { sniffXmlDecl } from "@suaveplan/mime/charset/sniff-xml-decl"; import { sniffBom } from "@suaveplan/mime/charset/sniff-bom"; function detectXmlEncoding(bytes: Uint8Array): string { // BOM overrides XML declaration per RFC 7303 §4.3 const bom = sniffBom(bytes); if (bom) return bom; // Use latin-1 to safely read the ASCII-range prolog const prolog = new TextDecoder("latin1").decode(bytes.slice(0, 256)); const declared = sniffXmlDecl(prolog); return declared ?? "utf-8"; // XML default encoding } // Single-quoted attribute const svgWithSingleQuotes = ""; console.log(sniffXmlDecl(svgWithSingleQuotes)); // "iso-8859-1" ``` ## API Reference ### `sniffXmlDecl(source: string): string | null` | Parameter | Type | Description | |-----------|------|-------------| | `source` | `string` | XML/SVG content (or the first chunk thereof). | **Returns:** The lowercase IANA encoding name, or `null` when no encoding attribute is found. **Throws:** Never. ## Implementation Notes The regex `/<\?xml[^?]*encoding\s*=\s*["']([^"']+)["']/i` intentionally uses `[^?]*` (non-greedy via exclusion) rather than `.*?` to avoid backtracking across large documents when no `