diff --git a/src/dom/xml-functions.ts b/src/dom/xml-functions.ts
index 0197d28..7082012 100644
--- a/src/dom/xml-functions.ts
+++ b/src/dom/xml-functions.ts
@@ -244,7 +244,7 @@ function xmlTransformedTextRecursive(node: XNode, buffer: string[], options: Xml
}
} else if (nodeType == DOM_COMMENT_NODE) {
if (options.outputMethod !== 'text') {
- buffer.push(``);
+ buffer.push(``);
}
} else if (nodeType === DOM_PROCESSING_INSTRUCTION_NODE) {
if (options.outputMethod !== 'text') {
diff --git a/src/dom/xml-parser.ts b/src/dom/xml-parser.ts
index 6db2e64..7a1425c 100644
--- a/src/dom/xml-parser.ts
+++ b/src/dom/xml-parser.ts
@@ -159,14 +159,14 @@ export class XmlParser {
}
if (htmlText.slice(i + 1, i + 4) === '!--') {
let endTagIndex = htmlText.slice(i + 4).indexOf('-->');
- if (endTagIndex) {
+ if (endTagIndex >= 0) {
let node = domCreateComment(xmlDocument, htmlText.slice(i + 4, i + endTagIndex + 4));
domAppendChild(parent, node);
i += endTagIndex + 6;
}
} else if (htmlText.slice(i + 1, i + 9) === '!DOCTYPE') {
let endTagIndex = htmlText.slice(i + 9).indexOf('>');
- if (endTagIndex) {
+ if (endTagIndex >= 0) {
const dtdValue = htmlText.slice(i + 9, i + endTagIndex + 9).trimStart();
// TODO: Not sure if this is a good solution.
// Trying to implement this: https://github.com/DesignLiquido/xslt-processor/issues/30
@@ -289,21 +289,21 @@ export class XmlParser {
}
if (xml.slice(i + 1, i + 4) === '!--') {
let endTagIndex = xml.slice(i + 4).indexOf('-->');
- if (endTagIndex) {
+ if (endTagIndex >= 0) {
let node = domCreateComment(xmlDocument, xml.slice(i + 4, i + endTagIndex + 4));
domAppendChild(parent, node);
i += endTagIndex + 6;
}
} else if (xml.slice(i + 1, i + 9) === '![CDATA[') {
let endTagIndex = xml.slice(i + 9).indexOf(']]>');
- if (endTagIndex) {
+ if (endTagIndex >= 0) {
let node = domCreateCDATASection(xmlDocument, xml.slice(i + 9, i + endTagIndex + 9));
domAppendChild(parent, node);
i += endTagIndex + 11;
}
} else if (xml.slice(i + 1, i + 9) === '!DOCTYPE') { // "!DOCTYPE" can be used in a XSLT template.
let endTagIndex = xml.slice(i + 9).indexOf('>');
- if (endTagIndex) {
+ if (endTagIndex >= 0) {
const dtdValue = xml.slice(i + 9, i + endTagIndex + 9).trimStart();
// TODO: Not sure if this is a good solution.
// Trying to implement this: https://github.com/DesignLiquido/xslt-processor/issues/30
diff --git a/src/index.ts b/src/index.ts
index 668b563..c76a99a 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,3 +1,3 @@
export { XPath, ExprContext } from './xpath';
export { Xslt, XsltOptions } from './xslt';
-export { XmlParser, xmlEscapeText, XDocument, XNode, domDocumentToXDocument } from './dom';
+export { XmlParser, xmlEscapeText, xmlTransformedText, XDocument, XNode, domDocumentToXDocument } from './dom';
diff --git a/tests/xml/xml.test.tsx b/tests/xml/xml.test.tsx
index 8ea837c..6bbc490 100644
--- a/tests/xml/xml.test.tsx
+++ b/tests/xml/xml.test.tsx
@@ -1,6 +1,6 @@
import assert from 'assert';
-import { XmlParser, xmlText } from '../../src/dom';
+import { XmlParser, xmlText, xmlTransformedText } from '../../src/dom';
describe('General XML', () => {
it('Self-closing tags disabled', () => {
@@ -15,4 +15,18 @@ describe('General XML', () => {
});
assert.equal(outXmlString, '');
});
+
+ it('preserves comment boundaries in transformed serialization', () => {
+ const xmlString = '';
+
+ const xmlParser = new XmlParser();
+ const outXmlString = xmlTransformedText(xmlParser.xmlParse(xmlString), {
+ cData: true,
+ selfClosingTags: true,
+ escape: true,
+ outputMethod: 'xml'
+ });
+
+ assert.equal(outXmlString, xmlString);
+ });
});
diff --git a/tests/xslt/issue-187.test.ts b/tests/xslt/issue-187.test.ts
new file mode 100644
index 0000000..f95cc46
--- /dev/null
+++ b/tests/xslt/issue-187.test.ts
@@ -0,0 +1,43 @@
+import { Xslt, XmlParser } from '../../src/index';
+
+describe('Issue #187: Identity transformation adds spaces to comments', () => {
+ it('keeps comment content stable across repeated identity transforms', async () => {
+ const xslt = new Xslt();
+ const xmlParser = new XmlParser();
+
+ const xmlInput = '';
+ const stylesheet = xmlParser.xmlParse(`
+
+
+
+`);
+
+ const firstInputDoc = xmlParser.xmlParse(xmlInput);
+ const firstPass = await xslt.xsltProcess(firstInputDoc, stylesheet);
+ expect(firstPass).toBe(xmlInput);
+
+ const secondInputDoc = xmlParser.xmlParse(firstPass);
+ const secondPass = await xslt.xsltProcess(secondInputDoc, stylesheet);
+ expect(secondPass).toBe(firstPass);
+ });
+
+ it('keeps empty comments stable across repeated identity transforms', async () => {
+ const xslt = new Xslt();
+ const xmlParser = new XmlParser();
+
+ const xmlInput = '';
+ const stylesheet = xmlParser.xmlParse(`
+
+
+
+`);
+
+ const firstInputDoc = xmlParser.xmlParse(xmlInput);
+ const firstPass = await xslt.xsltProcess(firstInputDoc, stylesheet);
+ expect(firstPass).toBe(xmlInput);
+
+ const secondInputDoc = xmlParser.xmlParse(firstPass);
+ const secondPass = await xslt.xsltProcess(secondInputDoc, stylesheet);
+ expect(secondPass).toBe(firstPass);
+ });
+});
\ No newline at end of file