Skip to content

Commit

Permalink
Fixed issue with DOCTYPE parsing (chrisbottin/xml-formatter#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisbottin committed Jul 4, 2023
1 parent 54686af commit 1112e2a
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 49 deletions.
6 changes: 5 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,11 @@ function element(matchRoot: boolean): XmlParserNodeWrapper<XmlParserElementNode>
}

function doctype(): XmlParserNodeWrapper<XmlParserDocumentTypeNode>|undefined {
const m = match(/^<!DOCTYPE\s+\S+\s+SYSTEM[^>]*>/) || match(/^<!DOCTYPE\s+\S+\s+PUBLIC[^>]*>/) || match(/^<!DOCTYPE\s+\S+\s+\[[^\]]*]>/);
const m =
match(/^<!DOCTYPE\s+\S+\s+SYSTEM[^>]*>/) ||
match(/^<!DOCTYPE\s+\S+\s+PUBLIC[^>]*>/) ||
match(/^<!DOCTYPE\s+\S+\s*\[[^\]]*]>/) ||
match(/^<!DOCTYPE\s+\S+\s*>/);
if (m) {
const node: XmlParserDocumentTypeNode = {
type: 'DocumentType',
Expand Down
64 changes: 16 additions & 48 deletions test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,8 @@ describe('XML Parser', function() {

context('should support DOCTYPE', function() {

it('DOCTYPE with SYSTEM', function () {
const node = xmlParser('<?xml version="1.0" ?>\n<!DOCTYPE foo SYSTEM "foo.dtd">\n<foo></foo>');
function assertParser(doctype: string): void {
const node = xmlParser(`<?xml version="1.0" ?>\n${doctype}\n<foo></foo>`);

const root: XmlParserElementNode = {
type: 'Element',
Expand All @@ -510,62 +510,30 @@ describe('XML Parser', function() {
},
root: root,
children: [
{type: 'DocumentType', content: '<!DOCTYPE foo SYSTEM "foo.dtd">'},
{type: 'DocumentType', content: doctype},
root
]
});
}

it('DOCTYPE with SYSTEM', function () {
assertParser('<!DOCTYPE foo SYSTEM "foo.dtd">');
});

it('DOCTYPE with PUBLIC', function () {
const node = xmlParser('<?xml version="1.0" ?>\n<!DOCTYPE name PUBLIC "-//Beginning XML//DTD Address Example//EN">\n<foo></foo>');

const root: XmlParserElementNode = {
type: 'Element',
name: 'foo',
attributes: {},
children: []
};

assert.deepEqual(node, {
declaration: {
name: 'xml',
type: 'ProcessingInstruction',
attributes: {
version: '1.0'
}
},
root: root,
children: [
{type: 'DocumentType', content: '<!DOCTYPE name PUBLIC "-//Beginning XML//DTD Address Example//EN">'},
root
]
});
assertParser('<!DOCTYPE name PUBLIC "-//Beginning XML//DTD Address Example//EN">');
});

it('DOCTYPE with inline entities', function () {
const node = xmlParser('<?xml version="1.0" ?>\n<!DOCTYPE foo [ <!ENTITY myentity1 "my entity value" >\n <!ENTITY myentity2 "my entity value" > ]>\n<foo></foo>');

const root: XmlParserElementNode = {
type: 'Element',
name: 'foo',
attributes: {},
children: []
};
assertParser('<!DOCTYPE foo [ <!ENTITY myentity1 "my entity value" >\n <!ENTITY myentity2 "my entity value" > ]>');
assertParser('<!DOCTYPE foo[<!ENTITY myentity1 "my entity value" >\n <!ENTITY myentity2 "my entity value" >]>');
});

assert.deepEqual(node, {
declaration: {
name: 'xml',
type: 'ProcessingInstruction',
attributes: {
version: '1.0'
}
},
root: root,
children: [
{type: 'DocumentType', content: '<!DOCTYPE foo [ <!ENTITY myentity1 "my entity value" >\n <!ENTITY myentity2 "my entity value" > ]>'},
root
]
});
it('DOCTYPE with empty inline entities', function () {
assertParser('<!DOCTYPE foo []>');
assertParser('<!DOCTYPE foo[]>');
assertParser('<!DOCTYPE foo [ ]>');
assertParser('<!DOCTYPE foo>');
});
});

Expand Down

0 comments on commit 1112e2a

Please sign in to comment.