Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/dom/xml-functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ function xmlTransformedTextRecursive(node: XNode, buffer: string[], options: Xml
}
} else if (nodeType == DOM_COMMENT_NODE) {
if (options.outputMethod !== 'text') {
buffer.push(`<!-- ${nodeValue} -->`);
buffer.push(`<!--${nodeValue}-->`);
}
} else if (nodeType === DOM_PROCESSING_INSTRUCTION_NODE) {
if (options.outputMethod !== 'text') {
Expand Down
10 changes: 5 additions & 5 deletions src/dom/xml-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,14 @@
}
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
Expand Down Expand Up @@ -289,28 +289,28 @@
}
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
const node = domCreateDTDSection(xmlDocument, dtdValue);
domAppendChild(parent, node);
i += endTagIndex + dtdValue.length + 5;
}

Check warning on line 313 in src/dom/xml-parser.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement

Check warning on line 313 in src/dom/xml-parser.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
} else {
tag = true;
}

Check warning on line 316 in src/dom/xml-parser.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -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';

Check warning on line 3 in src/index.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function

Check warning on line 3 in src/index.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function

Check warning on line 3 in src/index.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function

Check warning on line 3 in src/index.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function

Check warning on line 3 in src/index.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🕹️ Function is not covered

Warning! Not covered function
16 changes: 15 additions & 1 deletion tests/xml/xml.test.tsx
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand All @@ -15,4 +15,18 @@ describe('General XML', () => {
});
assert.equal(outXmlString, '<root><typeA></typeA><typeB></typeB></root>');
});

it('preserves comment boundaries in transformed serialization', () => {
const xmlString = '<root><!--1234567890 1234567890--></root>';

const xmlParser = new XmlParser();
const outXmlString = xmlTransformedText(xmlParser.xmlParse(xmlString), {
cData: true,
selfClosingTags: true,
escape: true,
outputMethod: 'xml'
});

assert.equal(outXmlString, xmlString);
});
});
43 changes: 43 additions & 0 deletions tests/xslt/issue-187.test.ts
Original file line number Diff line number Diff line change
@@ -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 = '<root><!--1234567890 1234567890--></root>';
const stylesheet = xmlParser.xmlParse(`<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>`);

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 = '<root><!----></root>';
const stylesheet = xmlParser.xmlParse(`<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>`);

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);
});
});
Loading