* Process accumulated keyword in ENTITY declaration. * Validates SYSTEM/PUBLIC/NDATA keywords and updates state.
()
| 669 | * Validates SYSTEM/PUBLIC/NDATA keywords and updates state. |
| 670 | */ |
| 671 | #processEntityKeyword(): void { |
| 672 | const kw = this.#entityCurrentKeyword; |
| 673 | this.#entityCurrentKeyword = ""; |
| 674 | |
| 675 | if (!kw) return; |
| 676 | |
| 677 | // Fast path: check exact matches first (most common case) |
| 678 | if (kw === "SYSTEM") { |
| 679 | if (this.#entityExternalType) { |
| 680 | this.#error("Duplicate external ID keyword in ENTITY declaration"); |
| 681 | } |
| 682 | this.#entityExternalType = "SYSTEM"; |
| 683 | return; |
| 684 | } |
| 685 | if (kw === "PUBLIC") { |
| 686 | if (this.#entityExternalType) { |
| 687 | this.#error("Duplicate external ID keyword in ENTITY declaration"); |
| 688 | } |
| 689 | this.#entityExternalType = "PUBLIC"; |
| 690 | return; |
| 691 | } |
| 692 | if (kw === "NDATA") { |
| 693 | // NDATA validation |
| 694 | if (this.#isParameterEntity) { |
| 695 | this.#error("Parameter entities cannot have NDATA declarations"); |
| 696 | } |
| 697 | if (!this.#entityExternalType) { |
| 698 | this.#error( |
| 699 | "NDATA can only follow SYSTEM or PUBLIC in ENTITY declaration", |
| 700 | ); |
| 701 | } |
| 702 | // Whitespace is required before NDATA - already handled by sawWhitespace check |
| 703 | return; |
| 704 | } |
| 705 | |
| 706 | // Check for case-sensitive keywords only when exact match failed (rare case) |
| 707 | const kwUpper = kw.toUpperCase(); |
| 708 | if (kwUpper === "SYSTEM") { |
| 709 | this.#error(`'${kw}' must be uppercase 'SYSTEM'`); |
| 710 | } else if (kwUpper === "PUBLIC") { |
| 711 | this.#error(`'${kw}' must be uppercase 'PUBLIC'`); |
| 712 | } else if (kwUpper === "NDATA") { |
| 713 | this.#error(`'${kw}' must be uppercase 'NDATA'`); |
| 714 | } |
| 715 | // Other keywords (like notation names after NDATA) are just ignored |
| 716 | } |
| 717 | |
| 718 | #emitDeclaration(target: string, content: string): void { |
| 719 | // XML 1.0 §2.6: Only exact lowercase "xml" is valid for XML declaration |