UNPKG

xml-helper-ts

Version:

A TypeScript library for XML parsing, validation with XSD schema, and XML/JSON conversion - built from scratch without external dependencies

96 lines 3.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.XmlToJsonConverter = void 0; class XmlToJsonConverter { constructor(options = {}) { this.options = { preserveAttributes: options.preserveAttributes ?? true, attributePrefix: options.attributePrefix ?? '@', textKey: options.textKey ?? '#text', ignoreNamespaces: options.ignoreNamespaces ?? false }; } convert(xmlNode) { return this.nodeToJson(xmlNode); } nodeToJson(node) { const result = {}; const nodeName = this.options.ignoreNamespaces ? this.getLocalName(node.name) : node.name; // Handle text-only nodes if (node.text !== undefined && node.children.length === 0 && Object.keys(node.attributes).length === 0) { return this.convertValue(node.text); } // Add attributes if (this.options.preserveAttributes && Object.keys(node.attributes).length > 0) { for (const [key, value] of Object.entries(node.attributes)) { const attrKey = this.options.ignoreNamespaces ? this.getLocalName(key) : key; result[this.options.attributePrefix + attrKey] = this.convertValue(value); } } // Handle mixed content (text + elements) if (node.text !== undefined && node.children.length > 0) { result[this.options.textKey] = this.convertValue(node.text); } // Process child elements const elementGroups = {}; for (const child of node.children) { if (child.name === '#text') { if (child.text !== undefined) { result[this.options.textKey] = this.convertValue(child.text); } continue; } const childName = this.options.ignoreNamespaces ? this.getLocalName(child.name) : child.name; const childValue = this.nodeToJson(child); if (!elementGroups[childName]) { elementGroups[childName] = []; } elementGroups[childName].push(childValue); } // Add grouped elements to result for (const [name, values] of Object.entries(elementGroups)) { if (values.length === 1) { result[name] = values[0]; } else { result[name] = values; } } // If result only has text content and no attributes, return the text directly if (Object.keys(result).length === 1 && result[this.options.textKey] !== undefined) { return result[this.options.textKey]; } // If result is empty and we have text, return the text if (Object.keys(result).length === 0 && node.text !== undefined) { return this.convertValue(node.text); } return result; } convertValue(value) { // Try to convert to appropriate types if (value === 'true') return true; if (value === 'false') return false; if (value === 'null') return null; // Try number conversion if (/^-?\d+$/.test(value)) { const num = parseInt(value, 10); if (num.toString() === value) return num; } if (/^-?\d*\.?\d+$/.test(value)) { const num = parseFloat(value); if (!isNaN(num) && num.toString() === value) return num; } return value; } getLocalName(name) { const colonIndex = name.indexOf(':'); return colonIndex === -1 ? name : name.substring(colonIndex + 1); } } exports.XmlToJsonConverter = XmlToJsonConverter; //# sourceMappingURL=xml-to-json.js.map