Skip to content
This repository was archived by the owner on Jan 7, 2021. It is now read-only.

Commit 9d4e812

Browse files
committed
Add: ability to specify custom coercion methods by name
If `options.coerce` is an object, coercion is `true` but any attribute/tag first checks the coercion object for a custom function under the tag/attribute name, before falling back to the default coercion.
1 parent 2b04f29 commit 9d4e812

File tree

4 files changed

+26
-6
lines changed

4 files changed

+26
-6
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ var options = {
5050

5151
* **object:** Returns a Javascript object instead of a JSON string
5252
* **reversible:** Makes the JSON reversible to XML (*)
53-
* **coerce:** Makes type coercion. i.e.: numbers and booleans present in attributes and element values are converted from string to its correspondent data types.
53+
* **coerce:** Makes type coercion. i.e.: numbers and booleans present in attributes and element values are converted from string to its correspondent data types. Coerce can be optionally defined as an object with specific methods of coercion based on attribute name or tag name, with fallback to default coercion.
5454
* **trim:** Removes leading and trailing whitespaces as well as line terminators in element values.
5555
* **arrayNotation:** XML child nodes are always treated as arrays
5656
* **sanitize:** Sanitizes the following characters present in element values:

lib/xml2json.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function startElement(name, attrs) {
1313
if(options.coerce) {
1414
// Looping here in stead of making coerce generic as object walk is unnecessary
1515
for(var key in attrs) {
16-
attrs[key] = coerce(attrs[key]);
16+
attrs[key] = coerce(attrs[key],key);
1717
}
1818
}
1919

@@ -62,7 +62,7 @@ function endElement(name) {
6262
currentObject['$t'] = sanitizer.sanitize(currentObject['$t']);
6363
}
6464

65-
currentObject['$t'] = coerce(currentObject['$t']);
65+
currentObject['$t'] = coerce(currentObject['$t'],name);
6666
}
6767

6868
if (currentElementName !== name) {
@@ -84,11 +84,14 @@ function endElement(name) {
8484
currentObject = ancestor;
8585
}
8686

87-
function coerce(value) {
87+
function coerce(value,key) {
8888
if (!options.coerce || value.trim() === '') {
8989
return value;
9090
}
9191

92+
if (typeof options.coerce[key] === 'function')
93+
return options.coerce[key](value);
94+
9295
var num = Number(value);
9396
if (!isNaN(num)) {
9497
return num;

test/fixtures/coerce.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
</stringValue>
88
</value>
99
<value>
10-
<moneyValue number='true' currencyId="USD">104.95
10+
<moneyValue number='true' currencyId="USD" text="123.45">104.95
1111
</moneyValue>
1212
</value>
1313
<value>
@@ -27,4 +27,7 @@
2727
<value>
2828
<stringValue>SmDZ8RlMIjDvlEW3KUibzj2Q</stringValue>
2929
</value>
30+
<value>
31+
<text>42.42</text>
32+
</value>
3033
</itemRecord>

test/test-coerce.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,24 @@ assert.strictEqual(result.itemRecord.value[0].longValue['$t'], 12345);
1313
assert.strictEqual(result.itemRecord.value[1].stringValue.number, false);
1414
assert.strictEqual(result.itemRecord.value[2].moneyValue.number, true);
1515
assert.strictEqual(result.itemRecord.value[2].moneyValue['$t'], 104.95);
16+
assert.strictEqual(result.itemRecord.value[2].moneyValue.text, 123.45);
17+
assert.strictEqual(result.itemRecord.value[8].text['$t'], 42.42);
18+
1619

1720
// Without coercion
1821
result = parser.toJson(data, {reversible: true, coerce: false, object: true});
1922
assert.strictEqual(result.itemRecord.value[0].longValue['$t'], '12345');
2023
assert.strictEqual(result.itemRecord.value[1].stringValue.number, 'false');
2124
assert.strictEqual(result.itemRecord.value[2].moneyValue.number, 'true');
22-
assert.strictEqual(result.itemRecord.value[2].moneyValue['$t'], '104.95');
25+
assert.strictEqual(result.itemRecord.value[2].moneyValue['$t'], '104.95');
26+
assert.strictEqual(result.itemRecord.value[2].moneyValue.text, '123.45');
27+
assert.strictEqual(result.itemRecord.value[8].text['$t'], '42.42');
28+
29+
// With coercien as an optional object
30+
var result = parser.toJson(data, {reversible: true, coerce: {text:String}, object: true});
31+
assert.strictEqual(result.itemRecord.value[0].longValue['$t'], 12345);
32+
assert.strictEqual(result.itemRecord.value[1].stringValue.number, false);
33+
assert.strictEqual(result.itemRecord.value[2].moneyValue.number, true);
34+
assert.strictEqual(result.itemRecord.value[2].moneyValue['$t'], 104.95);
35+
assert.strictEqual(result.itemRecord.value[2].moneyValue.text, '123.45');
36+
assert.strictEqual(result.itemRecord.value[8].text['$t'], '42.42');

0 commit comments

Comments
 (0)