js2xmlparser
Advanced tools
Comparing version 0.1.3 to 0.1.4
@@ -0,1 +1,10 @@ | ||
## 0.1.4 ## | ||
* Removed callFunctions option (functionality already provided by convertMap option) | ||
* Removed wrapArray option (functionality already provided by existing array functionality) | ||
* Escape numbers when at tbe beginning of an element name | ||
* Edits to documentation | ||
* Added tests | ||
* Added copyright headers to individual JS files | ||
## 0.1.3 ## | ||
@@ -21,2 +30,2 @@ | ||
* Initial release | ||
* Initial release |
@@ -1,109 +0,111 @@ | ||
var js2xmlparser = require("../lib/js2xmlparser.js"); | ||
/* jshint node:true */ | ||
console.log("EXAMPLE 1"); | ||
console.log("========="); | ||
/** | ||
* js2xmlparser | ||
* Copyright © 2012 Michael Kourlas and other contributors | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated | ||
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the | ||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to | ||
* permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the | ||
* Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
*/ | ||
var example1 = { | ||
"firstName": "John", | ||
"lastName": "Smith" | ||
}; | ||
(function() { | ||
"use strict"; | ||
console.log(js2xmlparser("person", example1)); | ||
console.log(); | ||
var js2xmlparser = require("../lib/js2xmlparser.js"); | ||
console.log("EXAMPLE 2"); | ||
console.log("========="); | ||
console.log("EXAMPLE 1"); | ||
console.log("========="); | ||
var example2 = { | ||
"firstName": "John", | ||
"lastName": "Smith", | ||
"dateOfBirth": new Date(1964, 7, 26), | ||
"address": { | ||
var example1 = { | ||
"firstName": "John", | ||
"lastName": "Smith" | ||
}; | ||
console.log(js2xmlparser("person", example1)); | ||
console.log(); | ||
console.log("EXAMPLE 2"); | ||
console.log("========="); | ||
var example2 = { | ||
"@": { | ||
"type": "home" | ||
"type": "individual" | ||
}, | ||
"streetAddress": "3212 22nd St", | ||
"city": "Chicago", | ||
"state": "Illinois", | ||
"zip": 10000 | ||
}, | ||
"phone": [ | ||
{ | ||
"firstName": "John", | ||
"lastName": "Smith", | ||
"dateOfBirth": new Date(1964, 7, 26), | ||
"address": { | ||
"@": { | ||
"type": "home" | ||
}, | ||
"#": "123-555-4567" | ||
"streetAddress": "3212 22nd St", | ||
"city": "Chicago", | ||
"state": "Illinois", | ||
"zip": 10000 | ||
}, | ||
{ | ||
"@": { | ||
"type": "cell" | ||
"phone": [ | ||
{ | ||
"@": { | ||
"type": "home" | ||
}, | ||
"#": "123-555-4567" | ||
}, | ||
"#": "456-555-7890" | ||
} | ||
], | ||
"email": function() {return "john@smith.com";}, | ||
"notes": "John's profile is not complete." | ||
}; | ||
{ | ||
"@": { | ||
"type": "cell" | ||
}, | ||
"#": "456-555-7890" | ||
} | ||
], | ||
"email": function() {return "john@smith.com";}, | ||
"notes": "John's profile is not complete." | ||
}; | ||
console.log(js2xmlparser("person", example2)); | ||
console.log(); | ||
console.log(js2xmlparser("person", example2)); | ||
console.log(); | ||
console.log("EXAMPLE 3"); | ||
console.log("========="); | ||
console.log("EXAMPLE 3"); | ||
console.log("========="); | ||
var example3 = { | ||
"phone": [ | ||
{ | ||
"@": { | ||
"type": "home" | ||
var example3 = { | ||
"email": function() {return "john@smith.com";}, | ||
"dateOfBirth": new Date(1964, 7, 26) | ||
}; | ||
var example3Options = { | ||
convertMap: { | ||
"[object Date]": function(date) { | ||
return date.toISOString(); | ||
}, | ||
"#": "123-555-4567" | ||
}, | ||
{ | ||
"@": { | ||
"type": "cell" | ||
}, | ||
"#": "456-555-7890" | ||
"[object Function]": function(func) { | ||
return func.toString(); | ||
} | ||
} | ||
] | ||
}; | ||
}; | ||
var example3Options = { | ||
wrapArray: { | ||
enabled: true | ||
} | ||
}; | ||
console.log(js2xmlparser("person", example3, example3Options)); | ||
console.log(); | ||
console.log(js2xmlparser("person", example3, example3Options)); | ||
console.log(); | ||
console.log("EXAMPLE 4"); | ||
console.log("========="); | ||
console.log("EXAMPLE 4"); | ||
console.log("========="); | ||
var example4 = { | ||
"notes": "John's profile is not complete." | ||
}; | ||
var example4 = { | ||
"notes": "John's profile is not complete." | ||
}; | ||
var example4Options = { | ||
useCDATA: true | ||
}; | ||
var example4Options = { | ||
useCDATA: true | ||
}; | ||
console.log(js2xmlparser("person", example4, example4Options)); | ||
console.log(); | ||
console.log("EXAMPLE 5"); | ||
console.log("========="); | ||
var example5 = { | ||
"dateOfBirth": new Date(1964, 7, 26) | ||
}; | ||
var example5Options = { | ||
convertMap: { | ||
"[object Date]": function(date) { | ||
return date.toISOString(); | ||
} | ||
} | ||
}; | ||
console.log(js2xmlparser("person", example5, example5Options)); | ||
console.log(js2xmlparser("person", example4, example4Options)); | ||
})(); |
@@ -1,11 +0,24 @@ | ||
/* globals module */ | ||
/* jshint node:true */ | ||
/** | ||
* js2xmlparser | ||
* Copyright © 2012 Michael Kourlas and other contributors | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated | ||
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the | ||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to | ||
* permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the | ||
* Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | ||
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS | ||
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
*/ | ||
(function() { | ||
"use strict"; | ||
var wrapArray = false; | ||
var wrapArrayItem = "item"; | ||
var callFunctions = true; | ||
var useCDATA = false; | ||
var convertMap = {}; | ||
var xmlDeclaration = true; | ||
@@ -18,2 +31,4 @@ var xmlVersion = "1.0"; | ||
var indentString = "\t"; | ||
var convertMap = {}; | ||
var useCDATA = false; | ||
@@ -33,2 +48,5 @@ module.exports = function (root, data, options) { | ||
} | ||
else if (root === "") { | ||
throw new Error("root element cannot be empty"); | ||
} | ||
@@ -56,36 +74,2 @@ // Error checking and variable initialization for options | ||
} | ||
if ("wrapArray" in options) { | ||
if ("enabled" in options.wrapArray) { | ||
if (typeof options.wrapArray.enabled === "boolean") { | ||
wrapArray = options.wrapArray.enabled; | ||
} | ||
else { | ||
throw new Error("wrapArray.enabled option must be a boolean"); | ||
} | ||
} | ||
if ("elementName" in options.wrapArray) { | ||
if (typeof options.wrapArray.elementName === "string") { | ||
wrapArrayItem = options.wrapArray.elementName; | ||
} | ||
else { | ||
throw new Error("wrapArray.elementName option must be a boolean"); | ||
} | ||
} | ||
} | ||
if ("useCDATA" in options) { | ||
if (typeof options.useCDATA === "boolean") { | ||
useCDATA = options.useCDATA; | ||
} | ||
else { | ||
throw new Error("useCDATA option must be a boolean"); | ||
} | ||
} | ||
if ("callFunctions" in options) { | ||
if (typeof options.callFunctions === "boolean") { | ||
callFunctions = options.callFunctions; | ||
} | ||
else { | ||
throw new Error("callFunctions option must be a boolean"); | ||
} | ||
} | ||
if ("attributeString" in options) { | ||
@@ -134,9 +118,26 @@ if (typeof options.attributeString === "string") { | ||
} | ||
if ("useCDATA" in options) { | ||
if (typeof options.useCDATA === "boolean") { | ||
useCDATA = options.useCDATA; | ||
} | ||
else { | ||
throw new Error("useCDATA option must be a boolean"); | ||
} | ||
} | ||
} | ||
// Error checking and variable initialization for data | ||
if (typeof data !== "string" && typeof data !== "object") { | ||
throw new Error("data must be an object or a string"); | ||
if (typeof data !== "string" && typeof data !== "object" && typeof data !== "number" && | ||
typeof data !== "boolean" && data !== null) { | ||
throw new Error("data must be an object (excluding arrays) or a JSON string"); | ||
} | ||
if (data === null) { | ||
throw new Error("data must be an object (excluding arrays) or a JSON string"); | ||
} | ||
if (Object.prototype.toString.call(data) === "[object Array]") { | ||
throw new Error("data must be an object (excluding arrays) or a JSON string"); | ||
} | ||
if (typeof data === "string") { | ||
@@ -158,19 +159,15 @@ data = JSON.parse(data); | ||
var i; | ||
var i = null; | ||
var tempObject = {}; | ||
for (var property in object) { | ||
// Arrays | ||
if (Object.prototype.toString.call(object[property]) === "[object Array]") { | ||
if (wrapArray) { | ||
// Create separate XML elements for each array element, but wrap all elements in a single element | ||
xml += addBreak(addIndent("<" + property + ">", level)); | ||
for (i = 0; i < object[property].length; i++) { | ||
tempObject = {}; | ||
tempObject[wrapArrayItem] = object[property][i]; | ||
xml = toXML(tempObject, xml, level + 1); | ||
} | ||
xml += addBreak(addIndent("</" + property + ">", level)); | ||
if (object.hasOwnProperty(property)) { | ||
// Element name cannot start with a number | ||
var elementName = property; | ||
if (/^\d/.test(property)) { | ||
elementName = "_" + property; | ||
} | ||
else { | ||
// Arrays | ||
if (Object.prototype.toString.call(object[property]) === "[object Array]") { | ||
// Create separate XML elements for each array element | ||
@@ -184,46 +181,53 @@ for (i = 0; i < object[property].length; i++) { | ||
} | ||
} | ||
// JSON-type objects with properties | ||
else if (Object.prototype.toString.call(object[property]) === "[object Object]") { | ||
// JSON-type objects with properties | ||
else if (Object.prototype.toString.call(object[property]) === "[object Object]") { | ||
xml += addIndent("<" + elementName, level); | ||
xml += addIndent("<" + property, level); | ||
// Add attributes | ||
var lengthExcludingAttributes = Object.keys(object[property]).length; | ||
if (Object.prototype.toString.call(object[property][attributeString]) === "[object Object]") { | ||
lengthExcludingAttributes -= 1; | ||
for (var attribute in object[property][attributeString]) { | ||
if (object[property][attributeString].hasOwnProperty(attribute)) { | ||
xml += " " + attribute + "=\"" + toString(object[property][attributeString][attribute]) + | ||
"\""; | ||
// Add attributes | ||
var lengthExcludingAttributes = Object.keys(object[property]).length; | ||
if (Object.prototype.toString.call(object[property][attributeString]) === "[object Object]") { | ||
lengthExcludingAttributes -= 1; | ||
for (var attribute in object[property][attributeString]) { | ||
if (object[property][attributeString].hasOwnProperty(attribute)) { | ||
xml += " " + attribute + "=\"" + | ||
toString(object[property][attributeString][attribute]) + "\""; | ||
} | ||
} | ||
} | ||
} | ||
else if (typeof object[property][attributeString] !== "undefined") { | ||
// Fix for the case where an object contains a single property with the attribute string as its | ||
// name, but this property contains no attributes; in that case, lengthExcludingAttributes | ||
// should be set to zero to ensure that the object is considered an empty object for the | ||
// purposes of the following if statement. | ||
lengthExcludingAttributes -= 1; | ||
} | ||
if (lengthExcludingAttributes === 0) { // Empty object | ||
xml += addBreak("/>"); | ||
} | ||
else if (lengthExcludingAttributes === 1 && valueString in object[property]) { // Value string only | ||
xml += addBreak(">" + toString(object[property][valueString], true) + "</" + property + ">"); | ||
} | ||
else { // Object with properties | ||
xml += addBreak(">"); | ||
if (lengthExcludingAttributes === 0) { // Empty object | ||
xml += addBreak("/>"); | ||
} | ||
else if (lengthExcludingAttributes === 1 && valueString in object[property]) { // Value string only | ||
xml += addBreak(">" + toString(object[property][valueString], true) + "</" + elementName + ">"); | ||
} | ||
else { // Object with properties | ||
xml += addBreak(">"); | ||
// Create separate object for each property and pass to this function | ||
for (var subProperty in object[property]) { | ||
if (subProperty !== attributeString) { | ||
tempObject = {}; | ||
tempObject[subProperty] = object[property][subProperty]; | ||
// Create separate object for each property and pass to this function | ||
for (var subProperty in object[property]) { | ||
if (object[property].hasOwnProperty(subProperty) && subProperty !== attributeString && subProperty !== valueString) { | ||
tempObject = {}; | ||
tempObject[subProperty] = object[property][subProperty]; | ||
xml = toXML(tempObject, xml, level + 1); | ||
xml = toXML(tempObject, xml, level + 1); | ||
} | ||
} | ||
xml += addBreak(addIndent("</" + elementName + ">", level)); | ||
} | ||
xml += addBreak(addIndent("</" + property + ">", level)); | ||
} | ||
// Everything else | ||
else { | ||
xml += addBreak(addIndent("<" + elementName + ">" + toString(object[property]) + "</" + | ||
elementName + ">", level)); | ||
} | ||
} | ||
// Everything else | ||
else { | ||
xml += addBreak(addIndent("<" + property + ">" + toString(object[property]) + "</" + property + ">", level)); | ||
} | ||
} | ||
@@ -290,8 +294,3 @@ | ||
else if (Object.prototype.toString.call(data) === "[object Function]") { | ||
if (callFunctions) { | ||
data = functionHelper(data()); | ||
} | ||
else { | ||
data = data.toString(); | ||
} | ||
data = functionHelper(data()); | ||
} | ||
@@ -325,5 +324,2 @@ // Empty objects | ||
var setOptionDefaults = function() { | ||
wrapArray = false; | ||
wrapArrayItem = "item"; | ||
callFunctions = true; | ||
useCDATA = false; | ||
@@ -330,0 +326,0 @@ convertMap = {}; |
@@ -6,4 +6,4 @@ { | ||
"homepage": "http://www.kourlas.net", | ||
"version": "0.1.3", | ||
"author": "Michael Kourlas <michaelkourlas@gmail.com>", | ||
"version": "0.1.4", | ||
"author": "Michael Kourlas <michael@kourlas.net>", | ||
"main": "./lib/js2xmlparser.js", | ||
@@ -14,3 +14,7 @@ "repository" : { | ||
}, | ||
"devDependencies": { | ||
"mocha": "*", | ||
"should": "*" | ||
}, | ||
"license": "MIT" | ||
} | ||
} |
111
README.md
@@ -1,2 +0,2 @@ | ||
# node-js2xmlparser # | ||
# js2xmlparser # | ||
@@ -35,27 +35,26 @@ ## Overview ## | ||
* `root` - string representing the XML root element's name | ||
* `data` - object or JSON string to be converted to XML | ||
* `options` - options object (optional) | ||
* `callFunctions` - if true, calls member functions (with no arguments) and includes their return value in the XML; | ||
if false, returns the text of the function (optional, default is true) | ||
* `wrapArray` - array wrapping options object (optional) | ||
* `enabled` - if true, all elements in an array will be added to a single XML element as child elements; if | ||
false, array elements will be placed in their own XML elements (optional, default is false) | ||
* `elementName` - name of XML child elements when array wrapping is enabled (optional, default is "item") | ||
* `useCDATA` - if true, all strings are enclosed in CDATA tags instead of escaping illegal XML characters (optional, | ||
default is false) | ||
* `convertMap` - object mapping certain types of objects (as given by `Object.prototype.toString.call(<object>)`) to | ||
functions to convert those types of objects to a particular string representation; "*" can be used as a wildcard | ||
for all types of objects (optional, default is an empty object) | ||
* `declaration` - XML declaration options object (optional) | ||
* `include` - if true, includes an XML declaration (optional, default is true) | ||
* `encoding` - string representing the XML encoding for the corresponding attribute in the declaration; a value | ||
of null represents no encoding attribute (optional, default is "UTF-8") | ||
* `attributeString` - string representing attribute property (optional, default is "@") | ||
* `valueString` - string representing the value property (optional, default is "#") | ||
* `prettyPrinting` - pretty-printing options object (optional) | ||
* `enabled` - if true, pretty-printing is enabled (optional, default is true) | ||
* `indentString` - string representing the indent (optional, default is "\t") | ||
* `root` - the XML root element's name (string, mandatory) | ||
* `data` - the data to be converted to XML; while the data object can contain arrays, it cannot itself be an array | ||
(object or JSON string, mandatory) | ||
* `options` - module options (object, optional) | ||
* `declaration` - XML declaration options (object, optional) | ||
* `include` - specifies whether an XML declaration should be included (boolean, optional, default: true) | ||
* `encoding` - value of XML encoding attribute in declaration; a value of null represents no encoding attribute | ||
(string, optional, default: "UTF-8") | ||
* `attributeString` - the name of the property representing an element's attributes; note that any property with a | ||
name equal to the attribute string is ignored except in the context of XML attributes (string, optional, default: | ||
"@") | ||
* `valueString` - the name of the property representing an element's value; note that any property with a name equal | ||
to the value string is ignored except in the context of supplying a value for a tag containing attributes (string, | ||
optional, default: "#") | ||
* `prettyPrinting` - pretty-printing options (object, optional) | ||
* `enabled` - specifies whether pretty-printing is enabled (boolean, optional, default: true) | ||
* `indentString` - indent string (string, optional, default: "\t") | ||
* `convertMap` - maps object types (as given by the `Object.prototype.toString.call` method) to functions to convert | ||
those objects to a particular string representation; `*` can be used as a wildcard for all types of objects | ||
(object, optional, default: {}) | ||
* `useCDATA` - specifies whether strings should be enclosed in CDATA tags; otherwise, illegal XML characters will | ||
be escaped (boolean, optional, default: false) | ||
## Example ## | ||
## Examples ## | ||
@@ -84,5 +83,8 @@ The following example illustrates the basic usage of js2xmlparser: | ||
var data = { | ||
"@": { | ||
"type": "individual" | ||
}, | ||
"firstName": "John", | ||
"lastName": "Smith", | ||
"dateOfBirth": new Date(1964, 07, 26), | ||
"dateOfBirth": new Date(1964, 7, 26), | ||
"address": { | ||
@@ -118,3 +120,3 @@ "@": { | ||
> <?xml version="1.0" encoding="UTF-8"?> | ||
> <person> | ||
> <person type="individual"> | ||
> <firstName>John</firstName> | ||
@@ -135,26 +137,15 @@ > <lastName>Smith</lastName> | ||
Here's an example that makes use of array wrapping: | ||
Here's an example that uses the convert map feature: | ||
var js2xmlparser = require("js2xmlparser"); | ||
var data = { | ||
"phone": [ | ||
{ | ||
"@": { | ||
"type": "home" | ||
}, | ||
"#": "123-555-4567" | ||
}, | ||
{ | ||
"@": { | ||
"type": "cell" | ||
}, | ||
"#": "456-555-7890" | ||
} | ||
] | ||
var data = { | ||
"dateOfBirth": new Date(1964, 7, 26) | ||
}; | ||
var options = { | ||
wrapArray: { | ||
enabled: true | ||
convertMap: { | ||
"[object Date]": function(date) { | ||
return date.toISOString(); | ||
} | ||
} | ||
@@ -167,6 +158,3 @@ }; | ||
> <person> | ||
> <phone> | ||
> <item type="home">123-555-4567</item> | ||
> <item type="cell">456-555-7890</item> | ||
> </phone> | ||
> <dateOfBirth>1964-08-26T04:00:00.000Z</dateOfBirth> | ||
> </person> | ||
@@ -193,23 +181,12 @@ | ||
Here's an example that uses the convert map feature: | ||
## Tests ## | ||
var js2xmlparser = require("js2xmlparser"); | ||
js2xmlparser comes with a set of tests that evaluate and verify the package's core functionality. To run the tests: | ||
var data = { | ||
"dateOfBirth": new Date(1964, 7, 26) | ||
}; | ||
* Install the test dependencies with `npm install`. | ||
* Run the tests with `mocha`. | ||
var options = { | ||
convertMap: { | ||
"[object Date]": function(date) { | ||
return date.toISOString(); | ||
} | ||
} | ||
}; | ||
## License ## | ||
console.log(js2xmlparser("person", data, options)); | ||
> <?xml version="1.0" encoding="UTF-8"?> | ||
> <person> | ||
> <dateOfBirth>1964-08-26T04:00:00.000Z</dateOfBirth> | ||
> </person> | ||
js2xmlparser is licensed under the [MIT license](http://opensource.org/licenses/MIT). Please see the LICENSE.md file | ||
for more information. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
84561
9
1537
2
187