UNPKG

partial-xml-stream-parser

Version:

A lenient XML stream parser for Node.js and browsers that can handle incomplete or malformed XML data, with depth control, CDATA support for XML serialization and round-trip parsing, wildcard pattern support for stopNodes, and CDATA handling within stopNo

74 lines (64 loc) 2.37 kB
import { initializeParserOptions, resetParserState } from "./parser-setup" import { processXmlChunk, finalizeStreamResult } from "./stream-processor" import { coreProcessBuffer } from "./core-parser" import { xmlObjectToString } from "./utils" import { ParserContext, ParserOptions, ParseResult } from "./types" export class PartialXMLStreamParser implements ParserContext { // Required ParserContext properties customOptions!: Required<ParserOptions> allowedRootNodes!: Set<string> | null attrRegex!: RegExp commentRegex!: RegExp cdataOpenRegex!: RegExp doctypeRegex!: RegExp xmlDeclRegex!: RegExp stopNodeRegexCache!: Record<string, RegExp> simpleStopNodes!: Set<string> pathStopNodes!: Set<string> streamingBuffer!: string _activelyStreaming!: boolean accumulator!: any[] currentPointer!: any tagStack!: any[] parsingIndex!: number incompleteStructureState!: any reparsedSegmentContext!: any streamingBufferBeforeClear!: string _originalBufferHadContent!: boolean _lastClearedIncompleteStateWasSpecial!: boolean _rootDeterminationBuffer!: string _plainTextAccumulator!: string _treatAsPlainText!: boolean _initialSegmentTypeDecided!: boolean constructor(options?: Partial<ParserOptions>) { initializeParserOptions(this, options) this.reset() } reset(): void { resetParserState(this) } private _processBuffer(): void { coreProcessBuffer(this) } parseStream(xmlChunk: string | Buffer | null | undefined): ParseResult { const chunkProcessingResult = processXmlChunk(this, xmlChunk) if (chunkProcessingResult.earlyExitResult) { return chunkProcessingResult.earlyExitResult } // Only call _processBuffer if the chunk processor determined it's necessary // and there's actually something in the streamingBuffer to process, // or if there's an incomplete state that needs resolving even with an empty new chunk. if ( chunkProcessingResult.shouldProcessBuffer && (this.streamingBuffer.length > 0 || this.incompleteStructureState) ) { this._processBuffer() } else if (chunkProcessingResult.shouldProcessBuffer && xmlChunk === null && this.incompleteStructureState) { // Special case for EOF with only incomplete state and empty buffer. this._processBuffer() } return finalizeStreamResult(this, xmlChunk) } } export { xmlObjectToString } export type { ParserOptions, ParseResult }