代码之家  ›  专栏  ›  技术社区  ›  punkish

分析XML以使用htmlparser2提取特定标记的文本

  •  0
  • punkish  · 技术社区  · 6 年前

    我正在尝试node-htmlparser2,一开始就被卡住了。我有数千个这样的XML文件:

    <document … loads of attribs …>
        <foo … loads of attribs …>
            <loads…> … </loads>
            <of…> … </of>
            <other…> … </other>
            <tags…> … </tags>
        </foo>
    </document>
    

    我想要里面的一切 <foo></foo> 作为单个字符串。我下面的代码有效,但在我看来这不是正确的方法

    let isFoo = false;
    let txt = '';
    const p = new htmlparser.Parser({
        onopentag: function(name, attribs){
            if (name === 'foo') {
                isFoo = true;
            }
        },
        ontext: function(text){
            if (isFoo) {
                txt += text;
            }
        },
        onclosetag: function(tagname){
            if (tagname === 'foo') {
                isFoo = false;
                return txt;
            }
        }
    }, {decodeEntities: true, xmlMode: true});
    
    let data = [];
    for (let file in files) {
        let record = {
            filename: file,
            filetext: p.write(file)
        }
        data.push(record);
        p.end();
    }
    

    有没有更好的方法可以在没有这种愚蠢的情况下使用htmlparser2? isFoo 旗帜?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Stock Overflaw    6 年前

    下面是一个可能的方法,灵感来自下面给出的示例 DomHandler's NPM page 从一个丑陋的 console.log h.DomUtils .

    const h = require('htmlparser2');
    const fs = require('fs');
    const data = []; // your output
    
    files.map((file) => { // files is assumed to be populated
      const record = {
        filename: file
      };
      data.push(record);
      const dh = new h.DomHandler((err, dom) => {
        if (err) return record.err = err;
        // DomUtils has many useful methods, most of them you know already, pick your preferred
        const e = h.DomUtils.getElementsByTagName('foo', dom)[0];
        // getText: only text nodes, getInnerHTML: everything, inner tags included
        record.filetext = h.DomUtils.getText(e);
      });
      const parser = new h.Parser(dh, {decodeEntities: true, xmlMode: true});
      fs.readFile(file, (err, content) => {
        if (err) return record.err = err;
        parser.write(content);
        parser.end();
      });
    });