public static fromXml()

in src/models/jObject.ts [41:156]


    public static fromXml(xml: string, parseCallbacks?: {
        attribute?: (value: string) => string,
        text?: (value: string) => string,
        cdata?: (value: string) => string,
        comment?: (value: string) => string,
    }): JObject {

        const root = new JObject("document");
        root.type = "document";
        const elementStack = [root];
        const parser = new Parser({ proxy: true });

        const pushChild = (element: JObject) => {
            const currentElement = elementStack[elementStack.length - 1];
            currentElement.children.push(element);

            elementStack.push(element);
        };

        const popChild = () => {
            elementStack.pop();
        };

        const pushSibling = (element: JObject) => {
            const currentElement = elementStack[elementStack.length - 1];
            currentElement.children.push(element);
        };

        parser.on("question", (str, decodeEntities, contextGetter) => {
            const element = new JObject("", "");
            element.type = "question";
            element.value = str;

            pushSibling(element);
        });

        parser.on("openTag", (el, decodeEntities, selfClosing, getContext) => {
            const elementNameParts = el.name.split(":");

            let elementNamespace: string;
            let elementName: string;

            if (elementNameParts.length > 1) {
                elementNamespace = elementNameParts[0];
                elementName = elementNameParts[1];
            } else {
                elementName = el.name;
            }

            const element = new JObject(elementName, elementNamespace);

            Object.keys(el.attrs).forEach(key => {
                const attributeNameParts = key.split(":");

                let attributeNamespace: string;
                let attributeName: string;

                if (attributeNameParts.length > 1) {
                    attributeNamespace = attributeNameParts[0];
                    attributeName = attributeNameParts[1];
                } else {
                    attributeName = key;
                }

                const tempValue = XmlUtil.decode(el.attrs[key]);
                const attributeValue = parseCallbacks && parseCallbacks.attribute ? parseCallbacks.attribute(tempValue) : tempValue;
                element.attributes.push(new JAttribute(attributeName, attributeValue, attributeNamespace));
            });

            if (el.attrs["template"] && el.attrs["template"].toUpperCase() === "LIQUID" || el.name === "xsl-transform") {
                element.type = "template";
            }

            pushChild(element);
        });

        parser.on("closeTag", (el, decodeEntities, selfClosing, getContext) => {
            popChild();
        });

        parser.on("error", (err, contextGetter) => {
            throw new Error("Unable to parse XML.");
        });

        parser.on("text", (text: string, decodeEntities, contextGetter) => {
            text = text.trim();

            if (!text) {
                return;
            }

            const currentElement = elementStack[elementStack.length - 1];

            if (!currentElement.value) {
                currentElement.value = "";
            }

            currentElement.value += parseCallbacks && parseCallbacks.text ? parseCallbacks.text(text) : text;
        });

        parser.on("cdata", (value: string) => {
            const element = new JObject("", "");
            element.value = parseCallbacks && parseCallbacks.cdata ? parseCallbacks.cdata(value) : value;
            element.type = "cdata";

            pushSibling(element);
        });

        parser.on("comment", (value: string,) => {
            pushSibling(new JComment(parseCallbacks && parseCallbacks.comment ? parseCallbacks.comment(value) : value));
        });

        parser.parse(xml);

        return root;
    }