Skip to content

Commit 9f859c7

Browse files
Call template text node (#85)
* Attaching text nodes to the output when the output is a document fragment. * - Always considering the output as being set, but this time we check the node type. If it is a document fragment, it means that a parent transformation is relying on that result; - Adjusting corner cases.
1 parent b9b64d1 commit 9f859c7

File tree

1 file changed

+28
-17
lines changed

1 file changed

+28
-17
lines changed

src/xslt/xslt.ts

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export class Xslt {
125125
}
126126
}
127127

128-
this.xsltProcessContext(expressionContext, stylesheet);
128+
this.xsltProcessContext(expressionContext, stylesheet, this.outputDocument);
129129
const transformedOutputXml = xmlTransformedText(outputDocument, {
130130
cData: false,
131131
escape: this.options.escape,
@@ -209,7 +209,7 @@ export class Xslt {
209209
if (modifiedContext.nodeList[j].nodeType === DOM_TEXT_NODE) {
210210
const textNodeContext = context.clone([modifiedContext.nodeList[j]], undefined, 0, undefined);
211211
// TODO: verify if it is okay to pass the own text node as template.
212-
this.commonLogicTextNode(textNodeContext, modifiedContext.nodeList[j]);
212+
this.commonLogicTextNode(textNodeContext, modifiedContext.nodeList[j], output);
213213
} else {
214214
const clonedContext = modifiedContext.clone(
215215
[modifiedContext.nodeList[j]],
@@ -236,7 +236,8 @@ export class Xslt {
236236
const documentFragment = domCreateDocumentFragment(this.outputDocument);
237237
this.xsltChildNodes(context, template, documentFragment);
238238
value = xmlValue2(documentFragment);
239-
if (output !== null && output !== undefined) {
239+
240+
if (output.nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {
240241
domSetTransformedAttribute(output, name, value);
241242
} else {
242243
let sourceNode = context.nodeList[context.position];
@@ -270,6 +271,10 @@ export class Xslt {
270271
parentSourceNode = newRootNode;
271272
}
272273

274+
// If the parent transformation is something like `xsl:element`, we should
275+
// add a copy of the attribute to this element.
276+
domSetTransformedAttribute(output, name, value);
277+
273278
// Some operations start by the tag attributes, and not by the tag itself.
274279
// When this is the case, the output node is not set yet, so
275280
// we add the transformed attributes into the original tag.
@@ -457,7 +462,8 @@ export class Xslt {
457462
value = attribute.stringValue();
458463
node = domCreateTransformedTextNode(this.outputDocument, value);
459464
node.siblingPosition = context.nodeList[context.position].siblingPosition;
460-
if (output !== null && output !== undefined) {
465+
466+
if (output.nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {
461467
output.appendTransformedChild(node);
462468
} else {
463469
context.outputNodeList[context.outputPosition].appendTransformedChild(node);
@@ -720,18 +726,23 @@ export class Xslt {
720726
* @param context The Expression Context.
721727
* @param template The template, that contains the node value to be written.
722728
*/
723-
private commonLogicTextNode(context: ExprContext, template: XNode) {
724-
const textNodeList = context.outputNodeList[context.outputPosition].transformedChildNodes.filter(
725-
(n) => n.nodeType === DOM_TEXT_NODE
726-
);
727-
728-
if (textNodeList.length > 0) {
729-
let node = textNodeList[0];
730-
node.transformedNodeValue = template.nodeValue;
731-
} else {
729+
private commonLogicTextNode(context: ExprContext, template: XNode, output: XNode) {
730+
if (output.nodeType === DOM_DOCUMENT_FRAGMENT_NODE) {
732731
let node = domCreateTransformedTextNode(this.outputDocument, template.nodeValue);
733-
node.transformedParentNode = context.outputNodeList[context.outputPosition];
734-
domAppendTransformedChild(context.outputNodeList[context.outputPosition], node);
732+
domAppendTransformedChild(output, node);
733+
} else {
734+
const textNodeList = context.outputNodeList[context.outputPosition].transformedChildNodes.filter(
735+
(n) => n.nodeType === DOM_TEXT_NODE
736+
);
737+
738+
if (textNodeList.length > 0) {
739+
let node = textNodeList[0];
740+
node.transformedNodeValue = template.nodeValue;
741+
} else {
742+
let node = domCreateTransformedTextNode(this.outputDocument, template.nodeValue);
743+
node.transformedParentNode = context.outputNodeList[context.outputPosition];
744+
domAppendTransformedChild(context.outputNodeList[context.outputPosition], node);
745+
}
735746
}
736747
}
737748

@@ -747,7 +758,7 @@ export class Xslt {
747758
protected xsltPassThrough(context: ExprContext, template: XNode, output: XNode) {
748759
if (template.nodeType == DOM_TEXT_NODE) {
749760
if (this.xsltPassText(template)) {
750-
this.commonLogicTextNode(context, template);
761+
this.commonLogicTextNode(context, template, output);
751762
}
752763
} else if (template.nodeType == DOM_ELEMENT_NODE) {
753764
let node: XNode;
@@ -795,7 +806,7 @@ export class Xslt {
795806
outputNode.transformedChildNodes.length - 1,
796807
++elementContext.outputDepth
797808
);
798-
this.xsltChildNodes(clonedContext, template);
809+
this.xsltChildNodes(clonedContext, template, output);
799810
} else {
800811
// This applies also to the DOCUMENT_NODE of the XSL stylesheet,
801812
// so we don't have to treat it specially.

0 commit comments

Comments
 (0)