Skip to content

Commit

Permalink
Feature/comments (#50)
Browse files Browse the repository at this point in the history
* add support for comments

* update changelog

* changelog: fix markdown

* add full support for comments (closes #47)

* readme: fix example 17 output
  • Loading branch information
davidcalhoun authored Jul 22, 2021
1 parent 18aa74e commit 579f1d8
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 29 deletions.
43 changes: 43 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Changelog

#### Version 2.2.0
* Initial support for XML comments ([#47](https://github.com/davidcalhoun/jstoxml/issues/47))

#### Version 2.1.1
* Fix for [#48](https://github.com/davidcalhoun/jstoxml/issues/48) (various 0-depth issues, bad "is output start" logic)

#### Version 2.0.0 (breaking)

- New: automatic entity escaping for `&`, `<`, and `>` characters. In addition, quotes `"` in attributes are also escaped (see [#41](/../../issues/41)). Prior to this, users [had to provide their own filter manually](https://github.com/davidcalhoun/jstoxml/issues/4#issuecomment-19165730). Note that `jstoxml` makes an effort not to escape entities that appear to have already been encoded, to prevent double-encoding issues.
- E.g. `toXML({ foo: '1 < 2 & 2 > 1' }); // -> "<foo>1 &lt; 2 &amp; 2 &gt; 1</foo>"`
- To restore the default behavior from `v1.x.x`, simply pass in `false` to `filter` and `attributesFilter` options:
`toXML({ foo: '1 < 2 & 2 > 1' }, { filter: false, attributesFilter: false }); // -> "<foo>1 < 2 & 2 > 1</foo>"`

#### Version 1.6.9

- fix for [#40](https://github.com/davidcalhoun/jstoxml/issues/47). Previously top-level objects and arrays were concatenated without proper line breaks.

#### Version 1.4.2

- support for handling arrays of primitives, instead of simply concatenating [#33](/../../issues/33)

#### Version 1.3.0

- restored `default` module export [#31](/../../issues/31)

#### Version 1.2.0

- refactoring and cleanup

#### Version 1.1.0

- Added support for attribute filtering (see Example 11b below).

#### Version 1.0.0

- Complete rewrite! The code should now be easier to understand and maintain.
- now supports emoji/UTF8 tag attributes (needed for AMP pages - e.g. `<html ⚡ lang="en">`) (see example 14)
- now supports duplicate attribute key names (see example 15)
- Fixed: functions returning objects now have now that output passed through toXML for XML conversion
- Fixed: empty text strings now properly output self-closing tags
- Migrated tests to mocha
82 changes: 54 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,41 +14,21 @@ This is inspired by [node-jsontoxml](https://github.com/soldair/node-jsontoxml),

### Changelog

#### Version 2.2.0
* Initial support for XML comments ([#47](https://github.com/davidcalhoun/jstoxml/issues/47))

#### Version 2.1.1
* Fix for [#48](https://github.com/davidcalhoun/jstoxml/issues/48) (various 0-depth issues, bad "is output start" logic)

#### Version 2.0.0 (breaking)

- New: automatic entity escaping for `&`, `<`, and `>` characters. In addition, quotes `"` in attributes are also escaped (see [#41](/../../issues/41)). Prior to this, users [had to provide their own filter manually](https://github.com/davidcalhoun/jstoxml/issues/4#issuecomment-19165730). Note that `jstoxml` makes an effort not to escape entities that appear to have already been encoded, to prevent double-encoding issues.
- E.g. `toXML({ foo: '1 < 2 & 2 > 1' }); // -> "<foo>1 &lt; 2 &amp; 2 &gt; 1</foo>"`
- To restore the default behavior from `v1.x.x`, simply pass in `false` to `filter` and `attributesFilter` options:
`toXML({ foo: '1 < 2 & 2 > 1' }, { filter: false, attributesFilter: false }); // -> "<foo>1 < 2 & 2 > 1</foo>"`

#### Version 1.6.9

- fix for [#40](/../../issues/40). Previously top-level objects and arrays were concatenated without proper line breaks.

#### Version 1.4.2

- support for handling arrays of primitives, instead of simply concatenating [#33](/../../issues/33)

#### Version 1.3.0

- restored `default` module export [#31](/../../issues/31)

#### Version 1.2.0

- refactoring and cleanup

#### Version 1.1.0

- Added support for attribute filtering (see Example 11b below).

#### Version 1.0.0

- Complete rewrite! The code should now be easier to understand and maintain.
- now supports emoji/UTF8 tag attributes (needed for AMP pages - e.g. `<html ⚡ lang="en">`) (see example 14)
- now supports duplicate attribute key names (see example 15)
- Fixed: functions returning objects now have now that output passed through toXML for XML conversion
- Fixed: empty text strings now properly output self-closing tags
- Migrated tests to mocha
#### Past changes
- See CHANGELOG.md for a full history of changes.

### Examples

Expand Down Expand Up @@ -703,6 +683,52 @@ Output:
<html lang="en" lang="klingon"/>
```

#### Example 16: XML comments

```javascript
toXML({
_comment: 'Some important comment',
a: {
b: [1, 2, 3]
}
}, { indent: ' ' });
```

Output:

```
<!-- Some important comment -->
<a>
<b>1</b>
<b>2</b>
<b>3</b>
</a>
```

#### Example 17: Multiple XML comments

```javascript
toXML([
{ _comment: 'Some important comment' },
{ _comment: 'This is a very long comment!' },
{ _comment: 'More important exposition!' },
{ a: { b: [1, 2, 3] } }
], { indent: ' ' });
```

Output:

```
<!-- Some important comment -->
<!-- This is a very long comment! -->
<!-- More important exposition! -->
<a>
<b>1</b>
<b>2</b>
<b>3</b>
</a>
```

### License

MIT
8 changes: 7 additions & 1 deletion jstoxml.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,12 @@ export const toXML = (obj = {}, config = {}) => {
const preIndentStr = (indent && !isOutputStart) ? "\n" : "";
const preTag = `${preIndentStr}${indentStr}`;

// Special handling for comments, preserving preceding line breaks/indents.
if (_name === '_comment') {
outputStr += `${preTag}<!-- ${_content} -->`;
break;
}

// Tag output.
const valIsEmpty = newValType === "undefined" || newVal === "";
const shouldSelfClose =
Expand All @@ -271,7 +277,7 @@ export const toXML = (obj = {}, config = {}) => {
const postTag = !shouldSelfClose
? `${newVal}${preTagCloseStr}</${_name}>`
: "";
outputStr = `${preTag}${tag}${postTag}`;
outputStr += `${preTag}${tag}${postTag}`;
break;
}

Expand Down
93 changes: 93 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1229,5 +1229,98 @@ describe("toXML", () => {
const expectedResult = `<a>A Value</a><b>B Value</b>`;
assert.equal(result, expectedResult);
});

it("comments 1", () => {
const val = {
_comment: "test comment",
a: "foo"
};
const result = toXML(val);
const expectedResult = `<!-- test comment --><a>foo</a>`;
assert.equal(result, expectedResult);
});

it("comments 2", () => {
const val = {
_comment: "test comment",
a: "foo"
};
const result = toXML(val, { indent: ' ' });
const expectedResult = `<!-- test comment -->
<a>foo</a>`;
assert.equal(result, expectedResult);
});

it("comments 3", () => {
const val = {
_comment: "comment 1",
b: {
_comment: "comment 2",
a: "foo"
}
};
const result = toXML(val, { indent: ' ' });
const expectedResult = `<!-- comment 1 -->
<b>
<!-- comment 2 -->
<a>foo</a>
</b>`;
assert.equal(result, expectedResult);
});

it("comments 4", () => {
const val = {
_comment: "comment 1",
b: [
{ _comment: "comment 2" },
{ _comment: "comment 3" },
{ a: "foo" }
]
};
const result = toXML(val, { indent: ' ' });
const expectedResult = `<!-- comment 1 -->
<b>
<!-- comment 2 -->
<!-- comment 3 -->
<a>foo</a>
</b>`;
assert.equal(result, expectedResult);
});
});

it("comments 5", () => {
const val = {
_comment: 'Some important comment',
a: {
b: [1, 2, 3]
}
};
const result = toXML(val, { indent: ' ' });
const expectedResult = `<!-- Some important comment -->
<a>
<b>1</b>
<b>2</b>
<b>3</b>
</a>`;
assert.equal(result, expectedResult);
});

it("comments 6", () => {
const val = [
{ _comment: 'Some important comment' },
{ _comment: 'This is a very long comment!' },
{ _comment: 'More important exposition!' },
{ a: { b: [1, 2, 3] } }
];
const result = toXML(val, { indent: ' ' });
const expectedResult = `<!-- Some important comment -->
<!-- This is a very long comment! -->
<!-- More important exposition! -->
<a>
<b>1</b>
<b>2</b>
<b>3</b>
</a>`;
assert.equal(result, expectedResult);
});
});

0 comments on commit 579f1d8

Please sign in to comment.