Last active
July 10, 2024 22:45
-
-
Save trulysinclair/5dc5832cee4d4e47299c376a7e1cd2b7 to your computer and use it in GitHub Desktop.
Convert xml2js output into badgerfish convention
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { toBadgerfish } from '#util/badgerfish/to_badgerfish' | |
import { JsonObject } from '#util/badgerfish/types' | |
import { Parser } from 'xml2js' | |
/** | |
* Convert XML to Badgerfish JSON convention | |
* @param {string} xml | |
* @returns {Promise<JsonObject>} | |
*/ | |
export async function fromXml(xml: string) { | |
const node: JsonObject = await new Parser({ | |
explicitArray: false, | |
trim: true, | |
normalize: true, | |
preserveChildrenOrder: true, | |
tagNameProcessors: [ | |
(tagName) => { | |
if (tagName.startsWith('xsi:')) { | |
return tagName.replace('xsi:', '') | |
} | |
return tagName | |
}, | |
], | |
}).parseStringPromise(xml) | |
return toBadgerfish(node) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { isValidChildProperty } from '#util/badgerfish/is_valid_child_property' | |
import { JsonObject } from '#util/badgerfish/types' | |
export function hasChildProperties(node: JsonObject): boolean { | |
if (typeof node !== 'object' || node === null) { | |
return false | |
} | |
const typedNode = node as JsonObject | |
for (let key in typedNode) { | |
if (isValidChildProperty(typedNode, key)) { | |
return true | |
} | |
} | |
return false | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { JsonObject } from '#util/badgerfish/types' | |
export function isValidChildProperty(node: JsonObject, key: string): boolean { | |
return node.hasOwnProperty(key) && typeof node[key] === 'object' && node[key] !== null | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { JsonObject } from '#util/badgerfish/types' | |
// TODO redo this in stages. i.e. handle namespaces, then values, then arrays, etc. | |
export function toBadgerfish(node: JsonObject) { | |
if (typeof node !== 'object' || node === null) return node | |
let badgerfishNode: JsonObject = {} | |
for (let key in node) { | |
if (node.hasOwnProperty(key)) { | |
// handle array | |
if (Array.isArray(node[key])) { | |
badgerfishNode[key] = (node[key] as Array<JsonObject>).map((i) => { | |
if (typeof i !== 'object') { | |
return { | |
$: toBadgerfish(i), | |
} | |
} else return toBadgerfish(i) | |
}) | |
} | |
// handle child object | |
else if (typeof node[key] === 'object') { | |
// handle attributes | |
if (key === '$') { | |
const namespace = {} | |
// go through each attribute, replacing the object for independent | |
// attributes prefixed with the "@" character | |
for (const attribute in node[key] as JsonObject) { | |
if (!attribute.includes('xmlns')) { | |
// @ts-ignore | |
badgerfishNode[`@${attribute}`] = node[key][attribute] | |
} else { | |
// append default namespace | |
if (attribute === 'xmlns') { | |
Object.assign(namespace, { | |
// @ts-ignore | |
$: node[key][attribute], | |
}) | |
} | |
// append named namespaces | |
else | |
Object.assign(namespace, { | |
// @ts-ignore | |
[attribute.replace('xmlns:', '')]: node[key][attribute], | |
}) | |
} | |
} | |
if (!Object.entries(namespace).length) { | |
// noop | |
} else badgerfishNode['@xmlns'] = namespace | |
} | |
// handle child objects | |
else badgerfishNode[key] = toBadgerfish(node[key] as JsonObject) | |
} | |
// Xml2Js puts text under "_", so put it in "$" | |
else if (key === '_') { | |
badgerfishNode['$'] = node[key] | |
} | |
// set values in "$" | |
else { | |
// handle text or attribute | |
badgerfishNode[key] = { $: node[key] } | |
} | |
} | |
} | |
return badgerfishNode | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export type JsonValue = string | number | boolean | JsonObject | JsonObject[] | |
export interface JsonObject { | |
[key: string]: JsonValue | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment