Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added optional comment handling #504

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,8 @@ value})``. Possible options are:
Version 0.1 default was `@`.
* `charkey` (default: `_`): Prefix that is used to access the character
content. Version 0.1 default was `#`.
* `commentskey` (default: `$comments`): Prefix that is used to access the comments.
* `parseComments` (default: `false`): Determines whether comments should be parsed.
* `explicitCharkey` (default: `false`)
* `trim` (default: `false`): Trim the whitespace at the beginning and end of
text nodes.
Expand Down Expand Up @@ -377,6 +379,7 @@ Possible options are:
Version 0.1 default was `@`.
* `charkey` (default: `_`): Prefix that is used to access the character
content. Version 0.1 default was `#`.
* `commentskey` (default: `$comments`): Prefix that is used to access the comments.
* `rootName` (default `root` or the root key name): root element name to be used in case
`explicitRoot` is `false` or to override the root element name.
* `renderOpts` (default `{ 'pretty': true, 'indent': ' ', 'newline': '\n' }`):
Expand Down
10 changes: 8 additions & 2 deletions lib/builder.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions lib/defaults.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 16 additions & 2 deletions lib/parser.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions src/builder.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class exports.Builder
buildObject: (rootObj) ->
attrkey = @options.attrkey
charkey = @options.charkey
commentskey = @options.commentskey

# If there is a sane-looking first element to use as the root,
# and the user hasn't specified a non-default rootName,
Expand Down Expand Up @@ -69,7 +70,12 @@ class exports.Builder
else
element = element.txt child

# Case #3 Array data
# Case #3 Comment
else if key is commentskey
for value in child
element = element.comment value

# Case #4 Array data
else if Array.isArray child
for own index, entry of child
if typeof entry is 'string'
Expand All @@ -80,11 +86,11 @@ class exports.Builder
else
element = render(element.ele(key), entry).up()

# Case #4 Objects
# Case #5 Objects
else if typeof child is "object"
element = render(element.ele(key), child).up()

# Case #5 String and remaining types
# Case #6 String and remaining types
else
if typeof child is 'string' && @options.cdata && requiresCDATA child
element = element.ele(key).raw(wrapCDATA child).up()
Expand Down
2 changes: 2 additions & 0 deletions src/defaults.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ exports.defaults = {
normalizeTags: false
attrkey: "$"
charkey: "_"
commentskey: "$comments"
parseComments: false
explicitArray: true
ignoreAttrs: false
mergeAttrs: false
Expand Down
9 changes: 9 additions & 0 deletions src/parser.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class exports.Parser extends events.EventEmitter
# aliases, so we don't have to type so much
attrkey = @options.attrkey
charkey = @options.charkey
commentskey = @options.commentskey

@saxParser.onopentag = (node) =>
obj = {}
Expand Down Expand Up @@ -225,6 +226,14 @@ class exports.Parser extends events.EventEmitter
if s
s.cdata = true

if @options.parseComments
@saxParser.oncomment = (text) =>
s = stack[stack.length - 1]
if s
s[commentskey] = s[commentskey] or []
s[commentskey].push text.slice(1,-1)
s

parseString: (str, cb) =>
if cb? and typeof cb is "function"
@on "end", (result) ->
Expand Down
2 changes: 1 addition & 1 deletion test/builder.test.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ module.exports =
fileName = path.join __dirname, '/fixtures/build_sample.xml'
fs.readFile fileName, (err, xmlData) ->
xmlExpected = xmlData.toString()
xml2js.parseString xmlData, {'trim': true}, (err, obj) ->
xml2js.parseString xmlData, {'trim': true, 'parseComments': true}, (err, obj) ->
equ err, null
builder = new xml2js.Builder({})
xmlActual = builder.buildObject obj
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/build_sample.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
<chartest desc="Test for CHARs">Character data here!</chartest>
<nochartest desc="No data" misc="false"/>
<nochildrentest desc="No data" misc="false"/>
<!-- This is the first sample comment! -->
<listtest>
<!-- This is the second sample comment! -->
<item>
This is
character
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/sample.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
<cdatawhitespacetest desc="Test for CDATA with whitespace" misc="true"><![CDATA[ ]]></cdatawhitespacetest>
<nochartest desc="No data" misc="false" />
<nochildrentest desc="No data" misc="false" />
<!-- This is the first sample comment! -->
<whitespacetest desc="Test for normalizing and trimming">
Line One
Line Two
</whitespacetest>
<listtest attr="Attribute">
<!-- This is the second sample comment! -->
<item>
This <subitem>Foo(1)</subitem> is
<subitem>Foo(2)</subitem>
Expand Down
49 changes: 27 additions & 22 deletions test/parser.test.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ module.exports =
# determine number of items in object
equ Object.keys(r.sample.tagcasetest[0]).length, 3)

'test parse with parseComments': skeleton(parseComments: true, (r) ->
console.log 'Result object: ' + util.inspect r, false, 10
equ r.sample.$comments[0], 'This is the first sample comment!'
equ r.sample.listtest[0].$comments[0], 'This is the second sample comment!')

'test parse with explicitCharkey': skeleton(explicitCharkey: true, (r) ->
console.log 'Result object: ' + util.inspect r, false, 10
equ r.sample.chartest[0].$.desc, 'Test for CHARs'
Expand Down Expand Up @@ -190,32 +195,32 @@ module.exports =

'test parse with explicitChildren and charsAsChildren and preserveChildrenOrder and includeWhiteChars': skeleton(explicitChildren: true, preserveChildrenOrder: true, charsAsChildren: true, includeWhiteChars: true, (r) ->
console.log 'Result object: ' + util.inspect r, false, 10
equ r.sample.$$[35]['#name'], 'textordertest'
equ r.sample.$$[35].$$[0]['#name'], '__text__'
equ r.sample.$$[35].$$[0]._, 'this is text with '
equ r.sample.$$[35].$$[1]['#name'], 'b'
equ r.sample.$$[35].$$[1]._, 'markup'
equ r.sample.$$[35].$$[2]['#name'], '__text__'
equ r.sample.$$[35].$$[2]._, ' '
equ r.sample.$$[35].$$[3]['#name'], 'em'
equ r.sample.$$[35].$$[3]._, 'like this'
equ r.sample.$$[35].$$[4]['#name'], '__text__'
equ r.sample.$$[35].$$[4]._, ' in the middle')
equ r.sample.$$[36]['#name'], 'textordertest'
equ r.sample.$$[36].$$[0]['#name'], '__text__'
equ r.sample.$$[36].$$[0]._, 'this is text with '
equ r.sample.$$[36].$$[1]['#name'], 'b'
equ r.sample.$$[36].$$[1]._, 'markup'
equ r.sample.$$[36].$$[2]['#name'], '__text__'
equ r.sample.$$[36].$$[2]._, ' '
equ r.sample.$$[36].$$[3]['#name'], 'em'
equ r.sample.$$[36].$$[3]._, 'like this'
equ r.sample.$$[36].$$[4]['#name'], '__text__'
equ r.sample.$$[36].$$[4]._, ' in the middle')

'test parse with explicitChildren and charsAsChildren and preserveChildrenOrder and includeWhiteChars and normalize': skeleton(explicitChildren: true, preserveChildrenOrder: true, charsAsChildren: true, includeWhiteChars: true, normalize: true, (r) ->
console.log 'Result object: ' + util.inspect r, false, 10
# normalized whitespace-only text node becomes empty string
equ r.sample.$$[35]['#name'], 'textordertest'
equ r.sample.$$[35].$$[0]['#name'], '__text__'
equ r.sample.$$[35].$$[0]._, 'this is text with'
equ r.sample.$$[35].$$[1]['#name'], 'b'
equ r.sample.$$[35].$$[1]._, 'markup'
equ r.sample.$$[35].$$[2]['#name'], '__text__'
equ r.sample.$$[35].$$[2]._, ''
equ r.sample.$$[35].$$[3]['#name'], 'em'
equ r.sample.$$[35].$$[3]._, 'like this'
equ r.sample.$$[35].$$[4]['#name'], '__text__'
equ r.sample.$$[35].$$[4]._, 'in the middle')
equ r.sample.$$[36]['#name'], 'textordertest'
equ r.sample.$$[36].$$[0]['#name'], '__text__'
equ r.sample.$$[36].$$[0]._, 'this is text with'
equ r.sample.$$[36].$$[1]['#name'], 'b'
equ r.sample.$$[36].$$[1]._, 'markup'
equ r.sample.$$[36].$$[2]['#name'], '__text__'
equ r.sample.$$[36].$$[2]._, ''
equ r.sample.$$[36].$$[3]['#name'], 'em'
equ r.sample.$$[36].$$[3]._, 'like this'
equ r.sample.$$[36].$$[4]['#name'], '__text__'
equ r.sample.$$[36].$$[4]._, 'in the middle')

'test element without children': skeleton(explicitChildren: true, (r) ->
console.log 'Result object: ' + util.inspect r, false, 10
Expand Down