@@ -215,6 +215,8 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
215
215
activeTag . language = parentTag . language ;
216
216
activeTag . direction = parentTag . direction ;
217
217
activeTag . baseIRI = parentTag . baseIRI ;
218
+ // Also inherit triple term collection array
219
+ activeTag . childrenTripleTerms = parentTag . childrenTripleTerms ;
218
220
} else {
219
221
activeTag . baseIRI = this . baseIRI ;
220
222
}
@@ -348,7 +350,7 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
348
350
if ( typedNode ) {
349
351
const type : RDF . NamedNode = this . uriToNamedNode ( tag . uri + tag . local ) ;
350
352
this . emitTriple ( activeTag . subject , this . dataFactory . namedNode ( RdfXmlParser . RDF + 'type' ) ,
351
- type , parentTag ? parentTag . reifiedStatementId : null ) ;
353
+ type , parentTag ? parentTag . reifiedStatementId : null , activeTag . childrenTripleTerms ) ;
352
354
}
353
355
354
356
if ( parentTag ) {
@@ -360,41 +362,43 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
360
362
361
363
// Emit <x> <p> <current-chain> OR <previous-chain> <rdf:rest> <current-chain>
362
364
this . emitTriple ( parentTag . childrenCollectionSubject ,
363
- parentTag . childrenCollectionPredicate , linkTerm , parentTag . reifiedStatementId ) ;
365
+ parentTag . childrenCollectionPredicate , linkTerm , parentTag . reifiedStatementId , parentTag . childrenTripleTerms ) ;
364
366
365
367
// Emit <current-chain> <rdf:first> value
366
368
this . emitTriple ( linkTerm , this . dataFactory . namedNode ( RdfXmlParser . RDF + 'first' ) ,
367
- activeTag . subject , activeTag . reifiedStatementId ) ;
369
+ activeTag . subject , activeTag . reifiedStatementId , activeTag . childrenTripleTerms ) ;
368
370
369
371
// Store <current-chain> in the parent node
370
372
parentTag . childrenCollectionSubject = linkTerm ;
371
373
parentTag . childrenCollectionPredicate = this . dataFactory . namedNode ( RdfXmlParser . RDF + 'rest' ) ;
372
374
} else { // !parentTag.predicateEmitted
373
375
// 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
+ }
375
380
376
381
// Emit pending properties on the parent tag that had no defined subject yet.
377
382
for ( let i = 0 ; i < parentTag . predicateSubPredicates . length ; i ++ ) {
378
383
this . emitTriple ( activeTag . subject , parentTag . predicateSubPredicates [ i ] ,
379
- parentTag . predicateSubObjects [ i ] , null ) ;
384
+ parentTag . predicateSubObjects [ i ] , null , parentTag . childrenTripleTerms ) ;
380
385
}
381
386
382
387
// Cleanup so we don't emit them again when the parent tag is closed
383
388
parentTag . predicateSubPredicates = [ ] ;
384
389
parentTag . predicateSubObjects = [ ] ;
385
- parentTag . predicateEmitted = true ;
386
390
}
387
391
}
388
392
389
393
// Emit all collected triples
390
394
for ( let i = 0 ; i < predicates . length ; i ++ ) {
391
395
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 ) ;
393
397
}
394
398
// Emit the rdf:type as named node instead of literal
395
399
if ( explicitType ) {
396
400
this . emitTriple ( activeTag . subject , this . dataFactory . namedNode ( RdfXmlParser . RDF + 'type' ) ,
397
- this . uriToNamedNode ( explicitType ) , null ) ;
401
+ this . uriToNamedNode ( explicitType ) , null , activeTag . childrenTripleTerms ) ;
398
402
}
399
403
}
400
404
}
@@ -505,7 +509,7 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
505
509
506
510
// Turn this property element into a node element
507
511
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 ) ;
509
513
activeTag . subject = nestedBNode ;
510
514
activeTag . predicate = null ;
511
515
} else if ( propertyAttribute . value === 'Collection' ) {
@@ -520,6 +524,11 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
520
524
// Interpret children as being part of a literal string
521
525
activeTag . childrenTagsToString = true ;
522
526
activeTag . childrenStringTags = [ ] ;
527
+ } else if ( propertyAttribute . value === 'Triple' ) {
528
+ parseType = true ;
529
+ // Collect children as triple terms
530
+ activeTag . childrenTagsToTripleTerms = true ;
531
+ activeTag . childrenTripleTerms = [ ] ;
523
532
}
524
533
continue ;
525
534
case 'ID' :
@@ -558,11 +567,11 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
558
567
const subjectParent : RDF . Term = activeTag . subject ;
559
568
activeTag . subject = subSubjectValueBlank
560
569
? 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 ) ;
562
571
563
572
// Emit our buffered triples
564
573
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 ) ;
566
575
}
567
576
activeTag . predicateEmitted = true ;
568
577
} else if ( subSubjectValueBlank ) {
@@ -582,10 +591,16 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
582
591
* @param {Term } object An object term.
583
592
* @param {Term } statementId An optional resource that identifies the triple.
584
593
* 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.
585
595
*/
586
596
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
+ }
589
604
590
605
// Reify triple
591
606
if ( statementId ) {
@@ -640,6 +655,8 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
640
655
*/
641
656
protected onCloseTag ( ) {
642
657
const poppedTag : IActiveTag = this . activeTagStack . pop ( ) ;
658
+ const parentTag : IActiveTag = this . activeTagStack . length
659
+ ? this . activeTagStack [ this . activeTagStack . length - 1 ] : null ;
643
660
644
661
// If we were converting a tag to a string, and the tag was not self-closing, close it here.
645
662
if ( poppedTag . childrenStringEmitClosingTag ) {
@@ -653,21 +670,32 @@ while ${attribute.value} and ${activeSubjectValue} where found.`);
653
670
poppedTag . hadChildren = false ; // Force a literal triple to be emitted hereafter
654
671
}
655
672
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
+
656
684
if ( poppedTag . childrenCollectionSubject ) {
657
685
// Terminate the rdf:List
658
686
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 ) ;
660
688
} else if ( poppedTag . predicate ) {
661
689
if ( ! poppedTag . hadChildren && poppedTag . childrenParseType !== ParseType . PROPERTY ) {
662
690
// Property element contains text
663
691
this . emitTriple ( poppedTag . subject , poppedTag . predicate , this . createLiteral ( poppedTag . text || '' , poppedTag ) ,
664
- poppedTag . reifiedStatementId ) ;
692
+ poppedTag . reifiedStatementId , poppedTag . childrenTripleTerms ) ;
665
693
} else if ( ! poppedTag . predicateEmitted ) {
666
694
// Emit remaining properties on an anonymous property element
667
695
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 ) ;
669
697
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 ) ;
671
699
}
672
700
}
673
701
}
@@ -752,6 +780,8 @@ export interface IActiveTag {
752
780
// for creating rdf:Lists
753
781
childrenCollectionSubject ?: RDF . NamedNode | RDF . BlankNode ;
754
782
childrenCollectionPredicate ?: RDF . NamedNode ;
783
+ childrenTagsToTripleTerms ?: boolean ;
784
+ childrenTripleTerms ?: RDF . Quad [ ] ;
755
785
}
756
786
757
787
export enum ParseType {
0 commit comments