import { DOMParser } from 'xmldom' import PersonGenerator from '../generators/PersonGenerator' export const resolvePeopleRefs = ( xml: string, people: Record = {} ): string => { const parser = new DOMParser() const dom = parser.parseFromString(xml, 'text/xml') // replace person nodes with their actual content const usePersonNodes = Array.from(dom.getElementsByTagName('UsePerson')) usePersonNodes.forEach( usePersonNode => { const personName = usePersonNode.getAttribute('ref') if (!personName) return // get the person generator for this tag const person = people[personName] if (!person) return // get the children of the tag // these are the nodes that need to be resolved const children = Array.from(usePersonNode.childNodes).filter((n) => n.nodeType === 1) // resolve the children nodes children.forEach((child) => { switch (child.nodeName) { case 'Sex': { const sex = person.sex const textNode = dom.createTextNode(sex) child.parentNode?.replaceChild(textNode, child) break } case 'Prefix': { const prefix = person.getName('{prefix}') const textNode = dom.createTextNode(prefix) child.parentNode?.replaceChild(textNode, child) break } case 'FirstName': { const firstName = person.getName('{firstName}') const textNode = dom.createTextNode(firstName) child.parentNode?.replaceChild(textNode, child) break } case 'LastName': { const lastName = person.getName('{lastName}') const textNode = dom.createTextNode(lastName) child.parentNode?.replaceChild(textNode, child) break } case 'MiddleName': { const middleName = person.getName('{middleName}') const textNode = dom.createTextNode(middleName) child.parentNode?.replaceChild(textNode, child) break } case 'FullName': { const fullName = person.getName() const textNode = dom.createTextNode(fullName) child.parentNode?.replaceChild(textNode, child) break } case 'Email': { const email = person.getEmail() const textNode = dom.createTextNode(email) child.parentNode?.replaceChild(textNode, child) break } case 'Phone': { const phone = person.getPhone() const textNode = dom.createTextNode(phone) child.parentNode?.replaceChild(textNode, child) break } case 'Address': { const address = person.getAddress() const textNode = dom.createTextNode(address) child.parentNode?.replaceChild(textNode, child) break } case 'Street': { const street = person.getAddress('{street}') const textNode = dom.createTextNode(street) child.parentNode?.replaceChild(textNode, child) break } case 'City': { const city = person.getAddress('{city}') const textNode = dom.createTextNode(city) child.parentNode?.replaceChild(textNode, child) break } case 'State': { const state = person.getAddress('{state}') const textNode = dom.createTextNode(state) child.parentNode?.replaceChild(textNode, child) break } case 'Zip': { const zip = person.getAddress('{zip}') const textNode = dom.createTextNode(zip) child.parentNode?.replaceChild(textNode, child) break } case 'Country': { const country = person.getAddress('{country}') const textNode = dom.createTextNode(country) child.parentNode?.replaceChild(textNode, child) break } default: throw new Error(`Unknown tag: ${child.nodeName}`) } }) // parent content is the child nodes of the node const parentContent = Array.from(usePersonNode.childNodes) // replace the node with the children nodes parentContent.forEach((child) => { usePersonNode.parentNode?.insertBefore(child, usePersonNode) }) usePersonNode.parentNode?.removeChild(usePersonNode) }) return dom.toString() }