Skip to content

Commit 1619007

Browse files
Multiple match bug (#62)
* Adjustments in transformations due to #49. * If template doesn't have attributes to set, clear transformed attributes.
1 parent f81f84c commit 1619007

File tree

4 files changed

+67
-16
lines changed

4 files changed

+67
-16
lines changed

src/dom/xml-functions.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ function xmlTransformedTextRecursive(node: XNode, buffer: any[], options: XmlOut
180180
buffer.push(`<![CDATA[${nodeValue}]]>`);
181181
}
182182
} else if (nodeType == DOM_COMMENT_NODE) {
183-
buffer.push(`<!--${nodeValue}-->`);
183+
buffer.push(`<!-- ${nodeValue} -->`);
184184
} else if (nodeType == DOM_ELEMENT_NODE) {
185185
// If node didn't have a transformed name, but its children
186186
// had transformations, children should be present at output.
@@ -207,7 +207,7 @@ function xmlTransformedTextRecursive(node: XNode, buffer: any[], options: XmlOut
207207
* @param buffer The XML buffer.
208208
* @param cdata If using CDATA configuration.
209209
*/
210-
function xmlElementLogicTrivial(node: XNode, buffer: any[], options: XmlOutputOptions) {
210+
function xmlElementLogicTrivial(node: XNode, buffer: string[], options: XmlOutputOptions) {
211211
buffer.push(`<${xmlFullNodeName(node)}`);
212212

213213
const attributes = node.transformedAttributes || node.attributes;
@@ -217,15 +217,13 @@ function xmlElementLogicTrivial(node: XNode, buffer: any[], options: XmlOutputOp
217217
continue;
218218
}
219219

220-
const attributeNodeName = attribute.transformedNodeName || attribute.nodeName;
221-
const attributeNodeValue = attribute.transformedNodeValue || attribute.nodeValue;
222-
if (attributeNodeName && attributeNodeValue) {
223-
buffer.push(` ${xmlFullNodeName(attribute)}="${xmlEscapeAttr(attributeNodeValue)}"`);
220+
if (attribute.transformedNodeName && attribute.transformedNodeValue) {
221+
buffer.push(` ${xmlFullNodeName(attribute)}="${xmlEscapeAttr(attribute.transformedNodeValue)}"`);
224222
}
225223
}
226224

227225
const childNodes = node.transformedChildNodes.length > 0 ? node.transformedChildNodes : node.childNodes;
228-
if (childNodes.length == 0) {
226+
if (childNodes.length === 0) {
229227
buffer.push('/>');
230228
} else {
231229
buffer.push('>');

src/dom/xnode.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,15 +309,19 @@ export class XNode {
309309
this.attributes.push(XNode.create(DOM_ATTRIBUTE_NODE, name, value, this));
310310
}
311311

312-
setTransformedAttribute(name: any, value: any) {
312+
setTransformedAttribute(name: string, value: any) {
313313
for (let i = 0; i < this.transformedAttributes.length; ++i) {
314-
if (this.transformedAttributes[i].nodeName == name) {
315-
this.transformedAttributes[i].nodeValue = `${value}`;
314+
if (this.transformedAttributes[i].nodeName === name) {
315+
this.transformedAttributes[i].transformedNodeName = name;
316+
this.transformedAttributes[i].transformedNodeValue = `${value}`;
316317
return;
317318
}
318319
}
319320

320-
this.transformedAttributes.push(XNode.create(DOM_ATTRIBUTE_NODE, name, value, this));
321+
const newAttribute = XNode.create(DOM_ATTRIBUTE_NODE, name, value, this);
322+
newAttribute.transformedNodeName = name;
323+
newAttribute.transformedNodeValue = value;
324+
this.transformedAttributes.push(newAttribute);
321325
}
322326

323327
setAttributeNS(namespace: any, name: any, value: any) {

src/xslt/xslt.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -550,25 +550,32 @@ export class Xslt {
550550
let node = textNodeList[0];
551551
node.transformedNodeValue = template.nodeValue;
552552
} else {
553-
let node = domCreateTextNode(outputDocument, template.nodeValue);
553+
let node = domCreateTransformedTextNode(outputDocument, template.nodeValue);
554554
domAppendTransformedChild(context.nodelist[context.position], node);
555555
}
556556
}
557557
} else if (template.nodeType == DOM_ELEMENT_NODE) {
558558
let node: XNode;
559+
let elementContext = context;
559560
if (context.nodelist[context.position].nodeName === '#document') {
560561
node = context.nodelist[context.position].firstChild;
562+
elementContext = context.clone([node], 0);
561563
} else {
562564
node = context.nodelist[context.position];
563565
}
564566

565567
node.transformedNodeName = template.nodeName;
566568
node.transformedLocalName = template.localName;
567569

568-
for (const attribute of template.attributes.filter((a: any) => a)) {
569-
const name = attribute.nodeName;
570-
const value = this.xsltAttributeValue(attribute.nodeValue, context);
571-
domSetTransformedAttribute(node, name, value);
570+
const templateAttributes = template.attributes.filter((a: any) => a);
571+
if (templateAttributes.length === 0) {
572+
node.transformedAttributes = [];
573+
} else {
574+
for (const attribute of templateAttributes) {
575+
const name = attribute.nodeName;
576+
const value = this.xsltAttributeValue(attribute.nodeValue, elementContext);
577+
domSetTransformedAttribute(node, name, value);
578+
}
572579
}
573580

574581
this.xsltChildNodes(context, template, node, _parameters);

tests/xslt.test.tsx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,48 @@ describe('xslt', () => {
8787
});
8888
});
8989

90+
describe('xsl:template', () => {
91+
it('Trivial', () => {
92+
const xmlString = (
93+
<root>
94+
<typeA />
95+
<typeB />
96+
</root>
97+
);
98+
99+
const xsltString = <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
100+
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" />
101+
<xsl:template match="*|/*">
102+
<outputUnknown original-name="{name(.)}">
103+
<xsl:apply-templates select="*" />
104+
</outputUnknown>
105+
</xsl:template>
106+
<xsl:template match="typeA">
107+
<outputA />
108+
</xsl:template>
109+
<xsl:template match="/*/typeB">
110+
<outputB>I have text!</outputB>
111+
</xsl:template>
112+
</xsl:stylesheet>
113+
114+
// Needs to be this way. `isomorphic-jsx rewrites `<outputA />` as `<outputA></outputA>`.
115+
const expectedOutString = `<outputUnknown original-name="root">`+
116+
`<outputA/>`+
117+
`<outputB>I have text!</outputB>`+
118+
`</outputUnknown>`;
119+
120+
const xsltClass = new Xslt();
121+
const xml = xmlParse(xmlString);
122+
const xslt = xmlParse(xsltString);
123+
const outXmlString = xsltClass.xsltProcess(
124+
xml,
125+
xslt
126+
);
127+
128+
assert.equal(outXmlString, expectedOutString);
129+
});
130+
});
131+
90132
describe('xsl:text', () => {
91133
it('disable-output-escaping', () => {
92134
const xml = <anything></anything>;

0 commit comments

Comments
 (0)