EdwardZZZ / articles

工作点滴记录
2 stars 0 forks source link

Xml parse #75

Open EdwardZZZ opened 4 years ago

EdwardZZZ commented 4 years ago
const pom = `
<dependencies version="1.0">
    <dependency>
        <groupId>----------</groupId>
        <artifactId>==========</artifactId>
        <version>1.0.0</version>
    </dependency>
    <dependency>
        <groupId>----------</groupId>
        <artifactId>==========</artifactId>
        <version>1.0.1</version>
    </dependency>
</dependencies>
<dependencies>
    <dependency>
        <groupId>----------</groupId>
        <artifactId>==========</artifactId>
        <version>1.0.0</version>
    </dependency>
    <dependency>
        <groupId>----------</groupId>
        <artifactId>==========</artifactId>
        <version>1.0.1</version>
    </dependency>
</dependencies>
`;

function parseXML(xmlStr) {
    const tree = [{
        tagName: 'ROOT',
        children: [],
    }];

    const pomArr = pom.split(/\n/);
    const tagReg = /<(\/?)([^<>]+)>/;

    let str = xmlStr;
    while (true) {
        if (pomArr.length === 0) break;

        const result = tagReg.exec(str);

        if (!result) {
            // 如果读取文件,此处为按行读取
            str += pomArr.shift();
            continue;
        }

        const [tag, tagSlash, tagContent] = result;
        const isEnd = tagSlash === '/';

        if (!isEnd) {
            const tagContentArr = tagContent.split(/\s/);
            const [tagName, ...tagAttrs] = tagContentArr;
            const obj = { tagName };

            if (tagAttrs.length > 0) {
                for (let tagAttr of tagAttrs) {
                    const [attrName, attrVal] = tagAttr.split('=');
                    if (attrName && attrVal && attrVal[0] === attrVal.slice(-1) && (attrVal[0] === '\'' || attrVal[0] === '"')) {
                        obj[attrName] = attrVal.slice(1, -1);
                    }
                }
            }

            if (tree.length > 0) {
                const { children = [] } = tree[tree.length - 1];

                tree[tree.length - 1].children = children.concat(obj);
            }

            tree.push(obj);
        } else {
            if (result.index !== 0) {
                const prevStr = str.substr(0, result.index);
                if (!/^\s+$/.test(prevStr)) {
                    tree[tree.length - 1].content = prevStr;
                }
            }
            tree.pop();
        }

        str = str.slice(tag.length + result.index);
    }

    return tree[0].children;
}

console.log(JSON.stringify(parseXML(pom), null, 4));