* Serializes an XML element and its children to a string.
( element: XmlElement, indent: string | undefined, depth: number, getIndent?: (depth: number) => string, )
| 89 | * Serializes an XML element and its children to a string. |
| 90 | */ |
| 91 | function serializeElement( |
| 92 | element: XmlElement, |
| 93 | indent: string | undefined, |
| 94 | depth: number, |
| 95 | getIndent?: (depth: number) => string, |
| 96 | ): string { |
| 97 | // Initialize indent cache on first call |
| 98 | const indentFn = getIndent ?? createIndentCache(indent); |
| 99 | const prefix = indentFn(depth); |
| 100 | const newline = indent !== undefined ? "\n" : ""; |
| 101 | |
| 102 | // Build tag name (with optional namespace prefix) |
| 103 | const tagName = element.name.prefix |
| 104 | ? `${element.name.prefix}:${element.name.local}` |
| 105 | : element.name.local; |
| 106 | |
| 107 | // Build attributes string |
| 108 | let attrsStr = ""; |
| 109 | for (const [name, value] of Object.entries(element.attributes)) { |
| 110 | attrsStr += ` ${name}="${encodeAttributeValue(value)}"`; |
| 111 | } |
| 112 | |
| 113 | // Self-closing tag if no children |
| 114 | if (element.children.length === 0) { |
| 115 | return `${prefix}<${tagName}${attrsStr}/>`; |
| 116 | } |
| 117 | |
| 118 | // Check if all children are inline content (text or cdata only) |
| 119 | const hasOnlyInlineContent = element.children.every( |
| 120 | (child) => child.type === "text" || child.type === "cdata", |
| 121 | ); |
| 122 | |
| 123 | if (hasOnlyInlineContent) { |
| 124 | // Inline: <tag>content</tag> (no indentation for content) |
| 125 | const content = element.children |
| 126 | .map((child) => serializeNode(child, undefined, 0, indentFn)) |
| 127 | .join(""); |
| 128 | return `${prefix}<${tagName}${attrsStr}>${content}</${tagName}>`; |
| 129 | } |
| 130 | |
| 131 | // Block: children on separate lines (when indenting) |
| 132 | const childContent = element.children |
| 133 | .map((child) => serializeNode(child, indent, depth + 1, indentFn)) |
| 134 | .join(newline); |
| 135 | |
| 136 | return `${prefix}<${tagName}${attrsStr}>${newline}${childContent}${newline}${prefix}</${tagName}>`; |
| 137 | } |
| 138 | |
| 139 | /** |
| 140 | * Serializes any XML node to a string. |
no test coverage detected