|
| 1 | +/** |
| 2 | + * Utility for extracting string values from DOM nodes (XNode / XPathNode objects). |
| 3 | + * |
| 4 | + * XNode element nodes store `nodeValue` as the literal string `"null"` because |
| 5 | + * their constructor coerces the value via template literals. Actual text content |
| 6 | + * lives in child text nodes (nodeType 3). This helper traverses the child tree |
| 7 | + * to produce the correct string value. |
| 8 | + */ |
| 9 | + |
| 10 | +/** |
| 11 | + * Extract the string value from a DOM node object. |
| 12 | + * |
| 13 | + * Returns `null` if `node` is not a recognizable node object (e.g. a plain |
| 14 | + * number, boolean, or string), so callers can fall through to other logic. |
| 15 | + */ |
| 16 | +export function getStringValueFromNode(node: any): string | null { |
| 17 | + if (node === null || node === undefined) return null; |
| 18 | + if (typeof node !== 'object') return null; |
| 19 | + if (typeof node.nodeType !== 'number') return null; |
| 20 | + |
| 21 | + // Text node or attribute node — value is stored directly in nodeValue |
| 22 | + if (node.nodeType === 3 || node.nodeType === 2) { |
| 23 | + const v = node.nodeValue; |
| 24 | + return (v !== null && v !== undefined && v !== 'null') ? String(v) : ''; |
| 25 | + } |
| 26 | + |
| 27 | + // Element node (or document node) — text content is in descendant text nodes |
| 28 | + if (node.nodeType === 1 || node.nodeType === 9) { |
| 29 | + const children: any[] = node.childNodes; |
| 30 | + if (!children || children.length === 0) return ''; |
| 31 | + |
| 32 | + let text = ''; |
| 33 | + for (const child of children) { |
| 34 | + if (child.nodeType === 3) { |
| 35 | + // Text node |
| 36 | + const v = child.nodeValue; |
| 37 | + if (v !== null && v !== undefined && v !== 'null') { |
| 38 | + text += String(v); |
| 39 | + } |
| 40 | + } else if (child.nodeType === 1) { |
| 41 | + // Recurse into child elements |
| 42 | + text += getStringValueFromNode(child) ?? ''; |
| 43 | + } |
| 44 | + // Skip attribute nodes (nodeType 2) and others |
| 45 | + } |
| 46 | + return text; |
| 47 | + } |
| 48 | + |
| 49 | + return null; |
| 50 | +} |
0 commit comments