diff --git a/src/streams.ts b/src/streams.ts index 558bf73..143d8e6 100644 --- a/src/streams.ts +++ b/src/streams.ts @@ -8,9 +8,14 @@ export interface XmlToJsonLinesTransformStreamOptions { class XmlToJsonLinesTransformStream extends Transform { private charactersToParse?: string; - constructor(private readonly options: XmlToJsonLinesTransformStreamOptions) { + private readonly openTag: string; + + private readonly closeTag: string; + + constructor(options: XmlToJsonLinesTransformStreamOptions) { super(); - // noop + this.openTag = `<${options.entryTagName}>`; + this.closeTag = ``; } // eslint-disable-next-line no-underscore-dangle @@ -18,26 +23,29 @@ class XmlToJsonLinesTransformStream extends Transform { try { const chunkStr = chunk.toString('utf-8'); if (typeof this.charactersToParse !== 'string') { - const firstEntryIndex = chunkStr.indexOf(`<${this.options.entryTagName}>`); + const firstEntryIndex = chunkStr.indexOf(this.openTag); this.charactersToParse = chunkStr.slice(firstEntryIndex); } else { this.charactersToParse += chunkStr; } let theCharacters = `${this.charactersToParse}`; - let nextOpenTagIndex = theCharacters.indexOf(`<${this.options.entryTagName}>`); - let nextCloseTagIndex = theCharacters.indexOf(``); - const closeTagLength = this.options.entryTagName.length + 3; + let nextOpenTagIndex = theCharacters.indexOf(this.openTag); + let nextCloseTagIndex = theCharacters.indexOf(this.closeTag); + let sliceEnd = nextCloseTagIndex + this.closeTag.length; do { - const xml = theCharacters - .slice(nextOpenTagIndex, nextCloseTagIndex + closeTagLength) - .replace(/&(.+?);/g, '$1'); // FIXME better handling of XML entities??? This makes the pipe hang for some reason - const json = xml2json(xml, { compact: true }); - this.push(`${json}\n`); - theCharacters = theCharacters.slice(nextCloseTagIndex + closeTagLength); - nextOpenTagIndex = theCharacters.indexOf(`<${this.options.entryTagName}>`); - nextCloseTagIndex = theCharacters.indexOf(``); - } while (nextOpenTagIndex !== -1 && nextCloseTagIndex !== -1); + if (nextOpenTagIndex > -1 && nextCloseTagIndex > -1) { + const xml = theCharacters + .slice(nextOpenTagIndex, sliceEnd) + .replace(/&(.+?);/g, '$1'); // FIXME better handling of XML entities??? This makes the pipe hang for some reason + const json = xml2json(xml, { compact: true }); + this.push(`${json}\n`); + theCharacters = theCharacters.slice(sliceEnd); + } + nextOpenTagIndex = theCharacters.indexOf(this.openTag); + nextCloseTagIndex = theCharacters.indexOf(this.closeTag); + sliceEnd = nextCloseTagIndex + this.closeTag.length; + } while (nextOpenTagIndex > -1 && nextCloseTagIndex > -1); this.charactersToParse = theCharacters; callback(null, ''); } catch (err) {