Advertisement
lignite0

JS-USE: XMLParser

Sep 3rd, 2020
1,886
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const fs = require('fs');
  2. const {Parser} = require('node-expat');
  3. const {Writable} = require('stream');
  4.  
  5. class XMLParser extends Writable {
  6.  
  7.     constructor() {
  8.         super();
  9.         this.stages = [''];
  10.         this.parser = new Parser('UTF-8');
  11.         this.elements = [];
  12.  
  13.         this.findingState = {
  14.             startElement: (tag, attributes) => {
  15.                 this.stages.push(tag);
  16.                 const path = this.stages.join('/');
  17.                 if (this.events.includes(path)) {
  18.                     this.recordingState.startElement(tag, attributes);
  19.                     this.currentState = this.recordingState;
  20.                 }
  21.             },
  22.             text: () => {
  23.                 // nothing
  24.             },
  25.             endElement: (tag) => {
  26.                 this.stages.pop();
  27.             }
  28.         }
  29.  
  30.         this.recordingState = {
  31.             startElement: (tag, attributes) => {
  32.                 const element = {
  33.                     "tag": tag,
  34.                     "attributes": attributes,
  35.                     "nodes": {},
  36.                     "text": "",
  37.                 };
  38.                 if (this.elements.length > 0) {
  39.                     const {nodes} = this.getLastElement();
  40.                     nodes[tag] = nodes[tag] || [];
  41.                     nodes[tag].push(element);
  42.                 }
  43.                 this.elements.push(element);
  44.             },
  45.             text: (text) => {
  46.                 this.getLastElement().text += text.trim();
  47.             },
  48.             endElement: (tag) => {
  49.                 const element = this.elements.pop();
  50.                 if (this.elements.length === 0) {
  51.                     const path = this.stages.join('/');
  52.                     this.emit(path, element);
  53.                     this.findingState.endElement(tag);
  54.                     this.currentState = this.findingState;
  55.                 }
  56.             }
  57.         }
  58.  
  59.         this.currentState = this.findingState;
  60.  
  61.         this.parser.on('startElement', (...args) => this.currentState.startElement(...args));
  62.         this.parser.on('endElement', (...args) => this.currentState.endElement(...args));
  63.         this.parser.on('text', (...args) => this.currentState.text(...args));
  64.  
  65.         this.parser.on('error', (error) => {
  66.         })
  67.     }
  68.  
  69.     on(eventName, listener) {
  70.         super.on(eventName, listener);
  71.         this.events = this.eventNames();
  72.     }
  73.  
  74.     getLastElement() {
  75.         return this.elements[this.elements.length - 1];
  76.     }
  77.  
  78.     _write(chunk, encoding, callback) {
  79.         this.parser.write(chunk);
  80.         callback();
  81.     }
  82. }
  83.  
  84. const xmlParser = new XMLParser();
  85.  
  86. xmlParser.on('/root/date', (ctx) => {
  87.      console.log(JSON.stringify(ctx));
  88. });
  89.  
  90. xmlParser.on('/root/categories/category', (ctx) => {
  91.     //console.log(JSON.stringify(ctx));
  92. });
  93.  
  94. xmlParser.on('/root/products/product', (ctx) => {
  95.     //console.log(JSON.stringify(ctx));
  96. });
  97.  
  98. xmlParser.parser.on('startElement', (name, attributes) => {
  99.     if (name === 'root') {
  100.         console.log(attributes['targetNamespace']);
  101.     }
  102. })
  103.  
  104. const stream = fs.createReadStream('file.xml');
  105. stream.pipe(xmlParser);
  106.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement