@@ -215,6 +215,8 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
215215 activeTag . language = parentTag . language ;
216216 activeTag . direction = parentTag . direction ;
217217 activeTag . baseIRI = parentTag . baseIRI ;
218+ // Also inherit triple term collection array
219+ activeTag . childrenTripleTerms = parentTag . childrenTripleTerms ;
218220 } else {
219221 activeTag . baseIRI = this . baseIRI ;
220222 }
@@ -348,7 +350,7 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
348350 if ( typedNode ) {
349351 const type : RDF . NamedNode = this . uriToNamedNode ( tag . uri + tag . local ) ;
350352 this . emitTriple ( activeTag . subject , this . dataFactory . namedNode ( RdfXmlParser . RDF + 'type' ) ,
351- type , parentTag ? parentTag . reifiedStatementId : null ) ;
353+ type , parentTag ? parentTag . reifiedStatementId : null , activeTag . childrenTripleTerms ) ;
352354 }
353355
354356 if ( parentTag ) {
@@ -360,41 +362,43 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
360362
361363 // Emit <x> <p> <current-chain> OR <previous-chain> <rdf:rest> <current-chain>
362364 this . emitTriple ( parentTag . childrenCollectionSubject ,
363- parentTag . childrenCollectionPredicate , linkTerm , parentTag . reifiedStatementId ) ;
365+ parentTag . childrenCollectionPredicate , linkTerm , parentTag . reifiedStatementId , parentTag . childrenTripleTerms ) ;
364366
365367 // Emit <current-chain> <rdf:first> value
366368 this . emitTriple ( linkTerm , this . dataFactory . namedNode ( RdfXmlParser . RDF + 'first' ) ,
367- activeTag . subject , activeTag . reifiedStatementId ) ;
369+ activeTag . subject , activeTag . reifiedStatementId , activeTag . childrenTripleTerms ) ;
368370
369371 // Store <current-chain> in the parent node
370372 parentTag . childrenCollectionSubject = linkTerm ;
371373 parentTag . childrenCollectionPredicate = this . dataFactory . namedNode ( RdfXmlParser . RDF + 'rest' ) ;
372374 } else { // !parentTag.predicateEmitted
373375 // Set-based properties
374- this . emitTriple ( parentTag . subject , parentTag . predicate , activeTag . subject , parentTag . reifiedStatementId ) ;
376+ if ( ! parentTag . childrenTagsToTripleTerms ) {
377+ this . emitTriple ( parentTag . subject , parentTag . predicate , activeTag . subject , parentTag . reifiedStatementId , parentTag . childrenTripleTerms ) ;
378+ parentTag . predicateEmitted = true ;
379+ }
375380
376381 // Emit pending properties on the parent tag that had no defined subject yet.
377382 for ( let i = 0 ; i < parentTag . predicateSubPredicates . length ; i ++ ) {
378383 this . emitTriple ( activeTag . subject , parentTag . predicateSubPredicates [ i ] ,
379- parentTag . predicateSubObjects [ i ] , null ) ;
384+ parentTag . predicateSubObjects [ i ] , null , parentTag . childrenTripleTerms ) ;
380385 }
381386
382387 // Cleanup so we don't emit them again when the parent tag is closed
383388 parentTag . predicateSubPredicates = [ ] ;
384389 parentTag . predicateSubObjects = [ ] ;
385- parentTag . predicateEmitted = true ;
386390 }
387391 }
388392
389393 // Emit all collected triples
390394 for ( let i = 0 ; i < predicates . length ; i ++ ) {
391395 const object : RDF . Term = this . createLiteral ( objects [ i ] , activeTag ) ;
392- this . emitTriple ( activeTag . subject , predicates [ i ] , object , parentTag . reifiedStatementId ) ;
396+ this . emitTriple ( activeTag . subject , predicates [ i ] , object , parentTag . reifiedStatementId , parentTag . childrenTripleTerms ) ;
393397 }
394398 // Emit the rdf:type as named node instead of literal
395399 if ( explicitType ) {
396400 this . emitTriple ( activeTag . subject , this . dataFactory . namedNode ( RdfXmlParser . RDF + 'type' ) ,
397- this . uriToNamedNode ( explicitType ) , null ) ;
401+ this . uriToNamedNode ( explicitType ) , null , activeTag . childrenTripleTerms ) ;
398402 }
399403 }
400404 }
@@ -505,7 +509,7 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
505509
506510 // Turn this property element into a node element
507511 const nestedBNode : RDF . BlankNode = this . dataFactory . blankNode ( ) ;
508- this . emitTriple ( activeTag . subject , activeTag . predicate , nestedBNode , activeTag . reifiedStatementId ) ;
512+ this . emitTriple ( activeTag . subject , activeTag . predicate , nestedBNode , activeTag . reifiedStatementId , activeTag . childrenTripleTerms ) ;
509513 activeTag . subject = nestedBNode ;
510514 activeTag . predicate = null ;
511515 } else if ( propertyAttribute . value === 'Collection' ) {
@@ -520,6 +524,11 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
520524 // Interpret children as being part of a literal string
521525 activeTag . childrenTagsToString = true ;
522526 activeTag . childrenStringTags = [ ] ;
527+ } else if ( propertyAttribute . value === 'Triple' ) {
528+ parseType = true ;
529+ // Collect children as triple terms
530+ activeTag . childrenTagsToTripleTerms = true ;
531+ activeTag . childrenTripleTerms = [ ] ;
523532 }
524533 continue ;
525534 case 'ID' :
@@ -558,11 +567,11 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
558567 const subjectParent : RDF . Term = activeTag . subject ;
559568 activeTag . subject = subSubjectValueBlank
560569 ? this . dataFactory . blankNode ( activeSubSubjectValue ) : this . valueToUri ( activeSubSubjectValue , activeTag ) ;
561- this . emitTriple ( subjectParent , activeTag . predicate , activeTag . subject , activeTag . reifiedStatementId ) ;
570+ this . emitTriple ( subjectParent , activeTag . predicate , activeTag . subject , activeTag . reifiedStatementId , activeTag . childrenTripleTerms ) ;
562571
563572 // Emit our buffered triples
564573 for ( let i = 0 ; i < predicates . length ; i ++ ) {
565- this . emitTriple ( activeTag . subject , predicates [ i ] , objects [ i ] , null ) ;
574+ this . emitTriple ( activeTag . subject , predicates [ i ] , objects [ i ] , null , activeTag . childrenTripleTerms ) ;
566575 }
567576 activeTag . predicateEmitted = true ;
568577 } else if ( subSubjectValueBlank ) {
@@ -582,10 +591,16 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
582591 * @param {Term } object An object term.
583592 * @param {Term } statementId An optional resource that identifies the triple.
584593 * If truthy, then the given triple will also be emitted reified.
594+ * @param childrenTripleTerms An optional array to push quads into instead of emitting them.
585595 */
586596 protected emitTriple ( subject : RDF . Quad_Subject , predicate : RDF . Quad_Predicate , object : RDF . Quad_Object ,
587- statementId ?: RDF . NamedNode ) {
588- this . push ( this . dataFactory . quad ( subject , predicate , object , this . defaultGraph ) ) ;
597+ statementId ?: RDF . NamedNode , childrenTripleTerms ?: RDF . Quad [ ] ) {
598+ const quad = this . dataFactory . quad ( subject , predicate , object , this . defaultGraph ) ;
599+ if ( childrenTripleTerms ) {
600+ childrenTripleTerms . push ( quad ) ;
601+ } else {
602+ this . push ( quad ) ;
603+ }
589604
590605 // Reify triple
591606 if ( statementId ) {
@@ -640,6 +655,8 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
640655 */
641656 protected onCloseTag ( ) {
642657 const poppedTag : IActiveTag = this . activeTagStack . pop ( ) ;
658+ const parentTag : IActiveTag = this . activeTagStack . length
659+ ? this . activeTagStack [ this . activeTagStack . length - 1 ] : null ;
643660
644661 // If we were converting a tag to a string, and the tag was not self-closing, close it here.
645662 if ( poppedTag . childrenStringEmitClosingTag ) {
@@ -653,21 +670,32 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
653670 poppedTag . hadChildren = false ; // Force a literal triple to be emitted hereafter
654671 }
655672
673+ // Set the triple term value if we were collecting triple terms
674+ if ( poppedTag . childrenTagsToTripleTerms && poppedTag . predicate ) {
675+ if ( poppedTag . childrenTripleTerms . length !== 1 ) {
676+ throw this . newParseError ( `Expected exactly one triple term in rdf:parseType="Triple" but got ${ poppedTag . childrenTripleTerms . length } ` ) ;
677+ }
678+ for ( const tripleTerm of poppedTag . childrenTripleTerms ) {
679+ this . emitTriple ( poppedTag . subject , poppedTag . predicate , tripleTerm , null , parentTag ?. childrenTripleTerms ) ;
680+ }
681+ poppedTag . predicateEmitted = true ;
682+ }
683+
656684 if ( poppedTag . childrenCollectionSubject ) {
657685 // Terminate the rdf:List
658686 this . emitTriple ( poppedTag . childrenCollectionSubject , poppedTag . childrenCollectionPredicate ,
659- this . dataFactory . namedNode ( RdfXmlParser . RDF + 'nil' ) , poppedTag . reifiedStatementId ) ;
687+ this . dataFactory . namedNode ( RdfXmlParser . RDF + 'nil' ) , poppedTag . reifiedStatementId , poppedTag . childrenTripleTerms ) ;
660688 } else if ( poppedTag . predicate ) {
661689 if ( ! poppedTag . hadChildren && poppedTag . childrenParseType !== ParseType . PROPERTY ) {
662690 // Property element contains text
663691 this . emitTriple ( poppedTag . subject , poppedTag . predicate , this . createLiteral ( poppedTag . text || '' , poppedTag ) ,
664- poppedTag . reifiedStatementId ) ;
692+ poppedTag . reifiedStatementId , poppedTag . childrenTripleTerms ) ;
665693 } else if ( ! poppedTag . predicateEmitted ) {
666694 // Emit remaining properties on an anonymous property element
667695 const subject : RDF . Term = this . dataFactory . blankNode ( ) ;
668- this . emitTriple ( poppedTag . subject , poppedTag . predicate , subject , poppedTag . reifiedStatementId ) ;
696+ this . emitTriple ( poppedTag . subject , poppedTag . predicate , subject , poppedTag . reifiedStatementId , poppedTag . childrenTripleTerms ) ;
669697 for ( let i = 0 ; i < poppedTag . predicateSubPredicates . length ; i ++ ) {
670- this . emitTriple ( subject , poppedTag . predicateSubPredicates [ i ] , poppedTag . predicateSubObjects [ i ] , null ) ;
698+ this . emitTriple ( subject , poppedTag . predicateSubPredicates [ i ] , poppedTag . predicateSubObjects [ i ] , null , poppedTag . childrenTripleTerms ) ;
671699 }
672700 }
673701 }
@@ -752,6 +780,8 @@ export interface IActiveTag {
752780 // for creating rdf:Lists
753781 childrenCollectionSubject ?: RDF . NamedNode | RDF . BlankNode ;
754782 childrenCollectionPredicate ?: RDF . NamedNode ;
783+ childrenTagsToTripleTerms ?: boolean ;
784+ childrenTripleTerms ?: RDF . Quad [ ] ;
755785}
756786
757787export enum ParseType {
0 commit comments