Skip to content

Instantly share code, notes, and snippets.

@pluma
Created November 12, 2017 00:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pluma/592e0e286e3d2efb8b48bd2d0b3c9e33 to your computer and use it in GitHub Desktop.
Save pluma/592e0e286e3d2efb8b48bd2d0b3c9e33 to your computer and use it in GitHub Desktop.
Converting JSONML to XML (without sanity checks)
function isObject(obj) {
if (!obj) return false;
if (typeof obj !== "object") return false;
if (Array.isArray(obj)) return false;
return true;
}
function* stringifyElement(element, indentLevel, depth = 0) {
const indent =
typeof indentLevel === "string"
? indentLevel
: " ".repeat(indentLevel * depth);
const nl = indentLevel ? "\n" : "";
if (Array.isArray(element)) {
const [tagName, ...children] = element;
const attributes = isObject(children[0]) ? children.shift() : {};
yield `${indent}<${tagName}`;
for (const key of Object.keys(attributes).sort()) {
const value = attributes[key];
yield ` ${key}="${value.replace(/"/g, "&quot;")}"`;
}
if (!children.length) {
yield ` />${nl}`;
} else if (children.length === 1 && !Array.isArray(children[0])) {
yield `>${String(children[0])}</${tagName}>${nl}`;
} else {
yield `>${nl}`;
for (const child of children) {
yield* stringifyElement(child, indentLevel, depth + 1);
}
yield `${indent}</${tagName}>${nl}`;
}
} else if (!nl) {
yield `${indent}${String(element)}${nl}`;
} else {
for (const line of String(element).split("\n")) {
yield `${indent}${line}${nl}`;
}
}
}
function stringify(jsonml, indentLevel = 0) {
if (!jsonml.length) return "";
return jsonml.reduce(
(str, element) =>
str + [...stringifyElement(element, indentLevel)].join(""),
""
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment