All files / src xml2js.ts

71.74% Statements 33/46
37.5% Branches 3/8
75% Functions 6/8
78.57% Lines 33/42
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 891x   1x   1x                       1x         1x 1x 1x 1x 1x     2x 2x 2x     1x 1x 1x           1x       1x 1x 1x     1x 1x 1x     1x       1x 1x     1x             1x 1x     1x       1x 1x         1x 1x      
import * as SAX from 'sax';
 
import { JsApi, Options } from './jsapi';
 
const saxOptions: SAX.SAXOptions = {
  trim: false,
  normalize: true,
  lowercase: true,
  xmlns: true,
  position: true,
};
 
/**
 * @param {String} data input data
 * @param {Function} callback
 */
export function xml2js(
  data,
  onSuccess: (jsApi: JsApi) => void,
  onFail: (error: string) => void,
) {
  const sax = SAX.parser(true, saxOptions);
  const root = new JsApi({ elem: '#document', content: [] });
  let current: JsApi = root;
  const stack = [root];
  let parsingError = false;
 
  function pushToContent(options: Options) {
    const newContent = new JsApi({ parentNode: current, ...options });
    (current.content = current.content || []).push(newContent);
    return newContent;
  }
 
  sax.onopentag = function(node) {
    const qualifiedTag = node as SAX.QualifiedTag;
    const elem = {
      elem: qualifiedTag.name,
      prefix: qualifiedTag.prefix,
      local: qualifiedTag.local,
      attrs: {} as any,
    };
    for (const name of Object.keys(qualifiedTag.attributes)) {
      const { value, prefix, local } = qualifiedTag.attributes[name];
      elem.attrs[name] = { name, value, prefix, local };
    }
    const jsApiElem = pushToContent(elem);
    current = jsApiElem;
    stack.push(jsApiElem);
  };
 
  sax.onclosetag = function() {
    stack.pop();
    current = stack[stack.length - 1];
  };
 
  sax.oncomment = function(comment) {
    pushToContent({ comment: { text: comment.trim() } });
  };
 
  sax.onprocessinginstruction = function(processingInstruction) {
    pushToContent({ processingInstruction });
  };
 
  sax.onerror = function(error) {
    error.message = 'Error in parsing SVG: ' + error.message;
    if (error.message.indexOf('Unexpected end') < 0) {
      throw error;
    }
  };
 
  sax.onend = function() {
    Iif (this.error) {
      onFail(this.error.message);
    } else {
      onSuccess(root);
    }
  };
 
  try {
    sax.write(data);
  } catch (e) {
    onFail(e.message);
    parsingError = true;
  }
  Eif (!parsingError) {
    sax.close();
  }
}