11import * as RDF from "@rdfjs/types" ;
22import { resolve } from "relative-to-absolute-iri" ;
3- import { createStream , SAXStream , Tag } from "sax " ;
4- import { PassThrough , Transform , TransformCallback } from "stream" ;
3+ import { SaxesParser , SaxesTagPlain } from "saxes " ;
4+ import { PassThrough , Transform } from "readable- stream" ;
55import EventEmitter = NodeJS . EventEmitter ;
66import { ParseError } from "./ParseError" ;
77import { DataFactory } from "rdf-data-factory" ;
@@ -52,9 +52,8 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
5252 private readonly dataFactory : RDF . DataFactory ;
5353 private readonly baseIRI : string ;
5454 private readonly defaultGraph ?: RDF . Quad_Graph ;
55- private readonly strict ?: boolean ;
5655 private readonly allowDuplicateRdfIds ?: boolean ;
57- private readonly saxStream : SAXStream ;
56+ private readonly saxParser : SaxesParser ;
5857
5958 private readonly activeTagStack : IActiveTag [ ] = [ ] ;
6059 private readonly nodeIds : { [ id : string ] : boolean } = { } ;
@@ -76,25 +75,20 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
7675 this . defaultGraph = this . dataFactory . defaultGraph ( ) ;
7776 }
7877
79- this . saxStream = createStream ( this . strict , { xmlns : false , position : this . trackPosition } ) ;
80-
81- // Workaround for an issue in SAX where non-strict mode either lower- or upper-cases all tags.
82- if ( ! this . strict ) {
83- ( < any > this . saxStream ) . _parser . looseCase = 'toString' ;
84- }
78+ this . saxParser = new SaxesParser ( { xmlns : false , position : this . trackPosition } ) ;
8579
8680 this . attachSaxListeners ( ) ;
8781 }
8882
8983 /**
9084 * Parse the namespace of the given tag,
9185 * and take into account the namespace of the parent tag that was already parsed.
92- * @param {Tag } tag A tag to parse the namespace from.
86+ * @param {SaxesTagPlain } tag A tag to parse the namespace from.
9387 * @param {IActiveTag } parentTag The parent tag, or null if this tag is the root.
9488 * @return {{[p: string]: string}[] } An array of namespaces,
9589 * where the last ones have a priority over the first ones.
9690 */
97- public static parseNamespace ( tag : Tag , parentTag ?: IActiveTag ) : { [ prefix : string ] : string } [ ] {
91+ public static parseNamespace ( tag : SaxesTagPlain , parentTag ?: IActiveTag ) : { [ prefix : string ] : string } [ ] {
9892 const thisNs : { [ prefix : string ] : string } = { } ;
9993 let hasNs : boolean = false ;
10094 for ( const attributeKey in tag . attributes ) {
@@ -184,9 +178,9 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
184178 return parsed ;
185179 }
186180
187- public _transform ( chunk : any , encoding : BufferEncoding , callback : TransformCallback ) {
181+ public _transform ( chunk : any , encoding : BufferEncoding , callback : ( error ?: Error | null , data ?: any ) => void ) {
188182 try {
189- this . saxStream . write ( chunk , encoding ) ;
183+ this . saxParser . write ( chunk ) ;
190184 } catch ( e ) {
191185 return callback ( e ) ;
192186 }
@@ -244,18 +238,18 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
244238 }
245239
246240 protected attachSaxListeners ( ) {
247- this . saxStream . on ( 'error' , ( error ) => this . emit ( 'error' , error ) ) ;
248- this . saxStream . on ( 'opentag' , this . onTag . bind ( this ) ) ;
249- this . saxStream . on ( 'text' , this . onText . bind ( this ) ) ;
250- this . saxStream . on ( 'closetag' , this . onCloseTag . bind ( this ) ) ;
251- this . saxStream . on ( 'doctype' , this . onDoctype . bind ( this ) ) ;
241+ this . saxParser . on ( 'error' , ( error ) => this . emit ( 'error' , error ) ) ;
242+ this . saxParser . on ( 'opentag' , this . onTag . bind ( this ) ) ;
243+ this . saxParser . on ( 'text' , this . onText . bind ( this ) ) ;
244+ this . saxParser . on ( 'closetag' , this . onCloseTag . bind ( this ) ) ;
245+ this . saxParser . on ( 'doctype' , this . onDoctype . bind ( this ) ) ;
252246 }
253247
254248 /**
255249 * Handle the given tag.
256- * @param {QualifiedTag } tag A SAX tag.
250+ * @param {SaxesTagPlain } tag A SAX tag.
257251 */
258- protected onTag ( tag : Tag ) {
252+ protected onTag ( tag : SaxesTagPlain ) {
259253 // Get parent tag
260254 const parentTag : IActiveTag = this . activeTagStack . length
261255 ? this . activeTagStack [ this . activeTagStack . length - 1 ] : null ;
@@ -306,12 +300,12 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
306300
307301 /**
308302 * Handle the given node element in resource-mode.
309- * @param {QualifiedTag } tag A SAX tag.
303+ * @param {SaxesTagPlain } tag A SAX tag.
310304 * @param {IActiveTag } activeTag The currently active tag.
311305 * @param {IActiveTag } parentTag The parent tag or null.
312306 * @param {boolean } rootTag If we are currently processing the root tag.
313307 */
314- protected onTagResource ( tag : Tag , activeTag : IActiveTag , parentTag : IActiveTag , rootTag : boolean ) {
308+ protected onTagResource ( tag : SaxesTagPlain , activeTag : IActiveTag , parentTag : IActiveTag , rootTag : boolean ) {
315309 const tagExpanded : IExpandedPrefix = RdfXmlParser . expandPrefixedTerm ( tag . name , activeTag . ns , this ) ;
316310
317311 activeTag . childrenParseType = ParseType . PROPERTY ;
@@ -342,7 +336,7 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
342336 let subjectValueBlank : boolean = false ;
343337 let explicitType : string = null ;
344338 for ( const attributeKey in tag . attributes ) {
345- const attributeValue : string = tag . attributes [ attributeKey ] ;
339+ const attributeValue = tag . attributes [ attributeKey ] ;
346340 const attributeKeyExpanded : IExpandedPrefix = RdfXmlParser . expandPrefixedTerm ( attributeKey , activeTag . ns , this ) ;
347341 if ( parentTag && attributeKeyExpanded . uri === RdfXmlParser . RDF ) {
348342 switch ( attributeKeyExpanded . local ) {
@@ -475,11 +469,11 @@ while ${attributeValue} and ${activeSubjectValue} where found.`);
475469
476470 /**
477471 * Handle the given property element in property-mode.
478- * @param {QualifiedTag } tag A SAX tag.
472+ * @param {SaxesTagPlain } tag A SAX tag.
479473 * @param {IActiveTag } activeTag The currently active tag.
480474 * @param {IActiveTag } parentTag The parent tag or null.
481475 */
482- protected onTagProperty ( tag : Tag , activeTag : IActiveTag , parentTag : IActiveTag ) {
476+ protected onTagProperty ( tag : SaxesTagPlain , activeTag : IActiveTag , parentTag : IActiveTag ) {
483477 const tagExpanded : IExpandedPrefix = RdfXmlParser . expandPrefixedTerm ( tag . name , activeTag . ns , this ) ;
484478
485479 activeTag . childrenParseType = ParseType . RESOURCE ;
@@ -508,11 +502,11 @@ while ${attributeValue} and ${activeSubjectValue} where found.`);
508502 // Collect all attributes as triples
509503 // Assign subject value only after all attributes have been processed, because baseIRI may change the final val
510504 let activeSubSubjectValue : string = null ;
511- let subSubjectValueBlank : boolean = true ;
505+ let subSubjectValueBlank = true ;
512506 const predicates : RDF . NamedNode [ ] = [ ] ;
513507 const objects : ( RDF . NamedNode | RDF . BlankNode | RDF . Literal ) [ ] = [ ] ;
514508 for ( const propertyAttributeKey in tag . attributes ) {
515- const propertyAttributeValue : string = tag . attributes [ propertyAttributeKey ] ;
509+ const propertyAttributeValue = tag . attributes [ propertyAttributeKey ] ;
516510 const propertyAttributeKeyExpanded : IExpandedPrefix = RdfXmlParser
517511 . expandPrefixedTerm ( propertyAttributeKey , activeTag . ns , this ) ;
518512 if ( propertyAttributeKeyExpanded . uri === RdfXmlParser . RDF ) {
@@ -755,7 +749,7 @@ while ${attributeValue} and ${activeSubjectValue} where found.`);
755749 */
756750 protected onDoctype ( doctype : string ) {
757751 doctype . replace ( / < ! E N T I T Y \s + ( [ ^ \s ] + ) \s + [ " ' ] ( [ ^ " ' ] + ) [ " ' ] \s * > / g, ( match , prefix , uri ) => {
758- ( < any > this . saxStream ) . _parser . ENTITIES [ prefix ] = uri ;
752+ this . saxParser . ENTITIES [ prefix ] = uri ;
759753 return '' ;
760754 } ) ;
761755 }
@@ -780,10 +774,6 @@ export interface IRdfXmlParserArgs {
780774 * The default graph for constructing quads.
781775 */
782776 defaultGraph ?: RDF . Term ;
783- /**
784- * If the internal SAX parser should parse XML in strict mode, and error if it is invalid.
785- */
786- strict ?: boolean ;
787777 /**
788778 * If the internal position (line, column) should be tracked an emitted in error messages.
789779 */
0 commit comments