diff --git a/.gitignore b/.gitignore index 1bd7226..24211de 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules *.swp +*.DS_Store diff --git a/README.md b/README.md index a86be1d..311974c 100644 --- a/README.md +++ b/README.md @@ -2,27 +2,90 @@ It does not parse the following elements: -* CDATA sections +* CDATA sections (*) * Processing instructions * XML declarations * Entity declarations * Comments -## Installation -`npm install xml2json` +## Installation +``` +$ npm install xml2json +``` ## Usage ```javascript var parser = require('xml2json'); var xml = "bar"; -var json = parser.toJson(xml); //returns an string containing the json structure by default +var json = parser.toJson(xml); //returns a string containing the JSON structure by default console.log(json); ``` -* if you want to get the Javascript object then you might want to invoke parser.toJson(xml, {object: true}); -* if you want a reversible json to xml then you should use parser.toJson(xml, {reversible: true}); -* if you want to override the default "$t" key name for a node's text value, specify the textNodeKey option. e.g., `parser.toJson(xml, {textNodeKey: "text"})` -* if you want to prevent xml node attributes from appearing in the json, specify attributes: false. e.g., `parser.toJson(xml, {attributes: false})`. The default behavior is attributes: true. +## API + +```javascript +parser.toJson(xml, options); +``` +```javascript +parser.toXml(json, options); +``` + +### Options object + +Default values: +```javascript +var options = { + object: false, + reversible: false, + coerce: true, + sanitize: true, + trim: true +}; +``` + +* **object:** Returns a Javascript object instead of a JSON string +* **reversible:** Makes the JSON reversible to XML (*) +* **coerce:** Makes type coercion. i.e.: numbers and booleans present in attributes and element values are converted from string to its correspondent data types. +* **trim:** Removes leading and trailing whitespaces as well as line terminators in element values. +* **sanitize:** Sanitizes the following characters present in element values: + +```javascript +var chars = { + '<': '<', + '>': '>', + '(': '(', + ')': ')', + '#': '#', + '&': '&', + '"': '"', + "'": ''' +}; +``` + + + + +(*) xml2json tranforms CDATA content to JSON, but it doesn't generate a reversible structure. ## License -Copyright 2011 BugLabs Inc. All rights reserved. +(The MIT License) + +Copyright 2012 BugLabs. All rights reserved. + +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. \ No newline at end of file diff --git a/bin/xml2json b/bin/xml2json new file mode 100644 index 0000000..6904c06 --- /dev/null +++ b/bin/xml2json @@ -0,0 +1,25 @@ +#!/usr/local/bin/node + +var xml2json = require('../'); +var pkg = require('../package.json'); + +var xml = ''; + +var args = process.argv.slice(2) +var arg = args[0] + +if (arg == '--version') { + console.log(pkg.version) + process.exit(0) +} + +process.stdin.on('data', function (data) { + xml += data; +}); + +process.stdin.resume(); + +process.stdin.on('end', function () { + json = xml2json.toJson(xml) + process.stdout.write(json + '\n') +}); diff --git a/lib/index.js b/lib/index.js index cf5c57c..3d82b9b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,4 +1,4 @@ var exports = module.exports; -exports.toJson = require('./xml2json'); -exports.toXml = require('./json2xml'); +exports.toJson = require('./xml2json'); +exports.toXml = require('./json2xml'); \ No newline at end of file diff --git a/lib/json2xml.js b/lib/json2xml.js index f45a7ca..37b8177 100644 --- a/lib/json2xml.js +++ b/lib/json2xml.js @@ -1,48 +1,65 @@ module.exports = function toXml(json, xml) { - var xml = xml || ''; - if (json instanceof Buffer) { - json = json.toString(); - } - var obj = null; - if (typeof(json) == 'string') { - try { - obj = JSON.parse(json); - } catch(e) { - throw new Error("The JSON structure is invalid"); - } - } else { - obj = json; - } + sanitize = require('./sanitize'); + + var xml = xml || ''; + if (json instanceof Buffer) { + json = json.toString(); + } - var keys = Object.keys(obj); - var len = keys.length; + var obj = null; + if (typeof(json) == 'string') { + try { + obj = JSON.parse(json); + } catch(e) { + throw new Error("The JSON structure is invalid"); + } + } else { + obj = json; + } - for (var i = 0; i < len; i++) { - var key = keys[i]; + var keys = Object.keys(obj); + var len = keys.length; + // First pass, extract strings only + for (var i = 0; i < len; i++) { + var key = keys[i], value = obj[key], isArray = Array.isArray(value); + if (typeof(obj[key]) == 'string' || isArray || typeof(obj[key]) == 'number') { + var it = isArray ? value : [value]; - if (Array.isArray(obj[key])) { - var elems = obj[key]; - var l = elems.length; - for (var j = 0; j < l; j++) { - xml += '<' + key + '>'; - xml = toXml(elems[j], xml); - xml += ''; - } - } else if (typeof(obj[key]) == 'object') { - xml += '<' + key + '>'; - xml = toXml(obj[key], xml); - xml += ''; - } else if (typeof(obj[key]) == 'string') { - if (key == '$t') { - xml += obj[key]; - } else { - xml = xml.replace(/>$/, ''); - xml += ' ' + key + "='" + obj[key] + "'>"; - } - } - } + it.forEach(function(subVal) { + if (typeof(subVal) != 'object') { + if (key == '$t') { + xml += subVal; + } else { + xml = xml.replace(/>$/, ''); + xml += ' ' + key + '="' + sanitize(subVal) + '">'; + } + } + }) + } + } - return xml; -}; + // Second path, now handle sub-objects and arrays + for (var i = 0; i < len; i++) { + var key = keys[i]; + if (Array.isArray(obj[key])) { + var elems = obj[key]; + var l = elems.length; + for (var j = 0; j < l; j++) { + var elem = elems[j]; + if (typeof(elem) == 'object') { + xml += '<' + key + '>'; + xml = toXml(elem, xml); + xml += ''; + } + } + } else if (typeof(obj[key]) == 'object') { + xml += '<' + key + '>'; + xml = toXml(obj[key], xml); + xml += ''; + } + } + + return xml; +}; \ No newline at end of file diff --git a/lib/sanitize.js b/lib/sanitize.js new file mode 100644 index 0000000..7f770f5 --- /dev/null +++ b/lib/sanitize.js @@ -0,0 +1,39 @@ +/** + * Simple sanitization. It is not intended to sanitize + * malicious element values. + * + * character | escaped + * < < + * > > + * ( ( + * ) ) + * # # + * & & + * " " + * ' ' + */ +var chars = { + '<': '<' + , '>': '>' + , '(': '(' + , ')': ')' + , '#': '#' + , '&': '&' + , '"': '"' + , "'": ''' +} + +module.exports = function (value) { + if (typeof value !== 'string') { + return value; + } + + Object.keys(chars).forEach(function(key) { + // not using the RegExp method, because in some cases I'm using + // characters that have a different meaning in RegExp usage. + // http://stackoverflow.com/questions/542232/in-javascript-how-can-i-perform-a-global-replace-on-string-with-a-variable-insi + value = value.split(key).join(chars[key]) + }); + + return value; +}; \ No newline at end of file diff --git a/lib/xml2json.js b/lib/xml2json.js index f9c4595..cd9737a 100644 --- a/lib/xml2json.js +++ b/lib/xml2json.js @@ -1,96 +1,164 @@ var expat = require('node-expat'); var fs = require('fs'); +var sanitize = require('./sanitize'); // This object will hold the final result. -var obj = currentObject = {}; +var obj = {}; +var currentObject = {}; var ancestors = []; +var currentElementName = null; var options = {}; //configuration options function startElement(name, attrs) { - // if options.attributes is false, throw away attributes - if (!options.attributes) attrs = {}; - - if (! (name in currentObject)) { - currentObject[name] = attrs; - } else if (! (currentObject[name] instanceof Array)) { - // Put the existing object in an array. - var newArray = [currentObject[name]]; - // Add the new object to the array. - newArray.push(attrs); - // Point to the new array. - currentObject[name] = newArray; - } else { - // An array already exists, push the attributes on to it. - currentObject[name].push(attrs); - } - - // Store the current (old) parent. - ancestors.push(currentObject); - - // We are now working with this object, so it becomes the current parent. - if (currentObject[name] instanceof Array) { - // If it is an array, get the last element of the array. - currentObject = currentObject[name][currentObject[name].length - 1]; - } else { - // Otherwise, use the object itself. - currentObject = currentObject[name]; - } + currentElementName = name; + if(options.coerce) { + // Looping here in stead of making coerce generic as object walk is unnecessary + for(key in attrs) { + attrs[key] = coerce(attrs[key]); + } + } + + if (! (name in currentObject)) { + if(options.arrayNotation) { + currentObject[name] = [attrs]; + } else { + currentObject[name] = attrs; + } + } else if (! (currentObject[name] instanceof Array)) { + // Put the existing object in an array. + var newArray = [currentObject[name]]; + // Add the new object to the array. + newArray.push(attrs); + // Point to the new array. + currentObject[name] = newArray; + } else { + // An array already exists, push the attributes on to it. + currentObject[name].push(attrs); + } + + // Store the current (old) parent. + ancestors.push(currentObject); + + // We are now working with this object, so it becomes the current parent. + if (currentObject[name] instanceof Array) { + // If it is an array, get the last element of the array. + currentObject = currentObject[name][currentObject[name].length - 1]; + } else { + // Otherwise, use the object itself. + currentObject = currentObject[name]; + } } function text(data) { - data = data.trim(); - if (!data.length) { - return; - } - currentObject[options.textNodeKey] = (currentObject[options.textNodeKey] || "") + data; + //console.log('->' + data + '<-'); + /*if (!data.trim().length) { + return; + }*/ + if (options.trim) { + data = data.trim(); + } + + if (options.sanitize) { + data = sanitize(data); + } + + currentObject['$t'] = coerce((currentObject['$t'] || '') + data); } function endElement(name) { - // This should check to make sure that the name we're ending - // matches the name we started on. - var ancestor = ancestors.pop(); - if (!options.reversible) { - if ((Object.keys(currentObject).length == 1) && (options.textNodeKey in currentObject)) { - if (ancestor[name] instanceof Array) { - ancestor[name].push(ancestor[name].pop()[options.textNodeKey]); - } else { - ancestor[name] = currentObject[options.textNodeKey]; - } - } - } - - currentObject = ancestor; + if (currentElementName !== name) { + delete currentObject['$t']; + } + // This should check to make sure that the name we're ending + // matches the name we started on. + var ancestor = ancestors.pop(); + if (!options.reversible) { + if (('$t' in currentObject) && (Object.keys(currentObject).length == 1)) { + if (ancestor[name] instanceof Array) { + ancestor[name].push(ancestor[name].pop()['$t']); + } else { + ancestor[name] = currentObject['$t']; + } + } + } + + currentObject = ancestor; } +function coerce(value) { + if (!options.coerce) { + return value; + } + + var num = Number(value); + if (!isNaN(num)) { + return num; + } + + var _value = value.toLowerCase(); + + if (_value == 'true' || _value == 'yes') { + return true; + } + + if (_value == 'false' || _value == 'no') { + return false; + } + + return value; +} + + +/** + * Parses xml to json using node-expat. + * @param {String|Buffer} xml The xml to be parsed to json. + * @param {Object} _options An object with options provided by the user. + * The available options are: + * - object: If true, the parser returns a Javascript object instead of + * a JSON string. + * - reversible: If true, the parser generates a reversible JSON, mainly + * characterized by the presence of the property $t. + * - sanitize_values: If true, the parser escapes any element value in the xml + * that has any of the following characters: <, >, (, ), #, #, &, ", '. + * + * @return {String|Object} A String or an Object with the JSON representation + * of the XML. + */ module.exports = function(xml, _options) { - var parser = new expat.Parser('UTF-8'); + var parser = new expat.Parser('UTF-8'); + + parser.on('startElement', startElement); + parser.on('text', text); + parser.on('endElement', endElement); - parser.on('startElement', startElement); - parser.on('text', text); - parser.on('endElement', endElement); + obj = currentObject = {}; + ancestors = []; + currentElementName = null; - obj = currentObject = {}; - ancestors = []; + options = { + object: false, + reversible: false, + coerce: true, + sanitize: true, + trim: true + }; - options = { - object: false, - reversible: false, - textNodeKey: '$t', - attributes: true - }; + for (var opt in _options) { + options[opt] = _options[opt]; + } - for (var opt in _options) { - options[opt] = _options[opt]; - } + if (!parser.parse(xml)) { + throw new Error('There are errors in your xml file: ' + parser.getError()); + } - if (!parser.parse(xml)) { - throw new Error('There are errors in your xml file: ' + parser.getError()); - } + if (options.object) { + return obj; + } - if (options.object) { - return obj; - } + var json = JSON.stringify(obj); - return JSON.stringify(obj); -}; + //See: http://timelessrepo.com/json-isnt-a-javascript-subset + json = json.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029'); + return json; +}; \ No newline at end of file diff --git a/package.json b/package.json index d305c0f..c230d2b 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,18 @@ -{ "name" : "xml2json", - "version": "0.2.4", - "author": "Andrew Turley", - "email": "aturley@buglabs.net", - "description" : "Converts xml to json and viceverza, using node-expat.", - "repository": "git://github.com/buglabs/node-xml2json.git", - "main": "index", - "contributors":[ {"name": "Camilo Aguilar", "email": "camilo@buglabs.net"}], - "dependencies": { - "node-expat": "1.4.1" - } +{ + "name" : "xml2json", + "version": "0.3.2", + "author": "Andrew Turley", + "email": "aturley@buglabs.net", + "description" : "Converts xml to json and viceverza, using node-expat.", + "repository": "git://github.com/buglabs/node-xml2json.git", + "main": "index", + "contributors":[ + { "name": "Camilo Aguilar", "email": "camilo.aguilar@gmail.com" } + ], + "dependencies": { + "node-expat": "2.0.0" + }, + "bin": { + "xml2json": "bin/xml2json" + } } - diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..5509140 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +*.DS_Store diff --git a/test/coerce-overhead.js b/test/coerce-overhead.js new file mode 100644 index 0000000..ba91b2f --- /dev/null +++ b/test/coerce-overhead.js @@ -0,0 +1,20 @@ +var fs = require('fs'); +var parser = require('../lib'); + +var file = __dirname + '/fixtures/large.xml'; + +var data = fs.readFileSync(file); + +// With coercion +var t0 = Date.now(); +for(var i = 0; i < 10000; i++) { + var result = parser.toJson(data, {reversible: true, coerce: true, object: true}); +} +console.log(Date.now() - t0); + +// Without coercion +var t0 = Date.now(); +for(var i = 0; i < 10000; i++) { + result = parser.toJson(data, {reversible: true, object: true}); +} +console.log(Date.now() - t0); diff --git a/test/fixtures/coerce.json b/test/fixtures/coerce.json new file mode 100644 index 0000000..52da96d --- /dev/null +++ b/test/fixtures/coerce.json @@ -0,0 +1 @@ +{"itemRecord":{"value":[{"longValue":"12345"},{"stringValue":{"number":"false","$t":"this is a string value"}},{"moneyValue":{"number":"true","currencyId":"USD","$t":"104.95"}},{"moneyValue":{"currencyId":"USD","$t":"104.95"}},{"longValue":"0","bool":{"id":"0","$t":"true"}},{"longValue":"0"},{"dateValue":"2012-02-16T17:03:33.000-07:00"},{"stringValue":"SmDZ8RlMIjDvlEW3KUibzj2Q"}]}} \ No newline at end of file diff --git a/test/fixtures/coerce.xml b/test/fixtures/coerce.xml new file mode 100644 index 0000000..6fb4a37 --- /dev/null +++ b/test/fixtures/coerce.xml @@ -0,0 +1,30 @@ + + + 12345 + + + this is a string value + + + + 104.95 + + + + 104.95 + + + + 0 + true + + + 0 + + + 2012-02-16T17:03:33.000-07:00 + + + SmDZ8RlMIjDvlEW3KUibzj2Q + + \ No newline at end of file diff --git a/test/fixtures/domain.xml b/test/fixtures/domain.xml index bca04e1..c8c1aa4 100644 --- a/test/fixtures/domain.xml +++ b/test/fixtures/domain.xml @@ -1 +1 @@ -QEmu-fedora-i686c7a5fdbd-cdaf-9455-926a-d65c16db18092192002192002hvm/usr/bin/qemu-system-x86_64cosa1cosa2cosa3 +QEmu-fedora-i686c7a5fdbd-cdaf-9455-926a-d65c16db18092192002192002hvm/usr/bin/qemu-system-x86_64cosa1cosa2cosa3 diff --git a/test/fixtures/entities-reversible.json b/test/fixtures/entities-reversible.json new file mode 100644 index 0000000..0b61ec3 --- /dev/null +++ b/test/fixtures/entities-reversible.json @@ -0,0 +1 @@ +{"SERVICE":{"keywords":"Daily & Tickets, Dollywood's Splash Country, \"DOUBLE\"","request_type":"GetMerchantKeywords","session_id":"tcgg.122419.587","status":"OK"}} diff --git a/test/fixtures/entities.json b/test/fixtures/entities.json new file mode 100644 index 0000000..0b61ec3 --- /dev/null +++ b/test/fixtures/entities.json @@ -0,0 +1 @@ +{"SERVICE":{"keywords":"Daily & Tickets, Dollywood's Splash Country, \"DOUBLE\"","request_type":"GetMerchantKeywords","session_id":"tcgg.122419.587","status":"OK"}} diff --git a/test/fixtures/entities.xml b/test/fixtures/entities.xml new file mode 100644 index 0000000..f68848c --- /dev/null +++ b/test/fixtures/entities.xml @@ -0,0 +1 @@ + diff --git a/test/fixtures/large.json b/test/fixtures/large.json new file mode 100644 index 0000000..27ab909 --- /dev/null +++ b/test/fixtures/large.json @@ -0,0 +1 @@ +{"soapenv:Envelope":{"xmlns:soapenv":"http://schemas.xmlsoap.org/soap/envelope/","soapenv:Header":{},"soapenv:Body":{"findInterminglingResponse":{"xmlns":"http://www.ebay.com/marketplace/search/v1/services","ack":"Success","version":"1.1.0","timestamp":"2012-01-20T01:36:25.904Z","extension":{"id":"3","version":"1.0.0","contentType":"text/html","value":"qds=0.1723&!_dcat_leaf=617,163826,617,163826,15077&pct=94.84&nai=44&nhalf=0&ncbt=0&nmq=2&!SIBE=avatar+blue+ray+3d,JPIA9PMIDQ8:7M&auctions=44&nbi=22&iat=4&trsi=0&prof=5841&nabi=16&fixedprices=4&!ptrid=Pr1062_10,Pr5841_2&pcc=2&nProdSur=2&tcatid=617"},"resultSummary":{"matchCount":"118","abridgedMatchCount":"113","lastUpdateTime":"2012-01-19T18:36:02.000-07:00"},"intermingleRecord":[{"productRecord":{"value":[{"longValue":"81996414"},{"stringValue":"Avatar (DVD, 2010)"},{"longValue":"78"},{"moneyValue":{"currencyId":"USD","$t":"4.0"}},{"dateValue":"2012-01-19T21:01:14"},{"moneyValue":{"currencyId":"USD","$t":"13.5"}},{"longValue":"34"},{"moneyValue":{"currencyId":"USD","$t":"3.96"}},{"longValue":"44"},{"stringValue":"http://i.ebayimg.com/22/!!d7WiF!EWM~$(KGrHqMOKikEvOnbKY1gBL9fO1lupQ~~_6.JPG?set_id=89040003C1"}]}},{"productRecord":{"value":[{"longValue":"82093597"},{"stringValue":"Avatar (Blu-ray/DVD, 2010, 2-Disc Set)"},{"longValue":"74"},{"moneyValue":{"currencyId":"USD","$t":"15.01"}},{"dateValue":"2012-01-19T19:12:15"},{"moneyValue":{"currencyId":"USD","$t":"20.0"}},{"longValue":"26"},{"moneyValue":{"currencyId":"USD","$t":"11.96"}},{"longValue":"48"},{"stringValue":"http://i.ebayimg.com/01/!!d8dfeQ!mM~$(KGrHqUOKjcEwhzOMI3VBMSIdcD!Yw~~_6.JPG?set_id=89040003C1"}]}},{"itemRecord":{"value":[{"longValue":"220931734658"},{"stringValue":"AVATAR 3D BLU-RAY FACTORY SEALED -new,sealed-"},{"moneyValue":{"currencyId":"USD","$t":"70.99"}},{"moneyValue":{"currencyId":"USD","$t":"79.99"}},{"longValue":"1"},{"longValue":"300"},{"dateValue":"2012-01-19T19:15:14.000-07:00"},{"stringValue":"Sm86FNl5NfYQDIhtWAUiWbqQ"}]}},{"itemRecord":{"value":[{"longValue":"170763800829"},{"stringValue":"Avatar 3D Blu-ray Disc - BRAND NEW - FACTORY SEALED - PANASONIC EXCLUSIVE"},{"moneyValue":{"currencyId":"USD","$t":"61.0"}},{"moneyValue":{"currencyId":"USD","$t":"74.99"}},{"longValue":"4"},{"longValue":["300","0"]},{"dateValue":"2012-01-19T19:51:57.000-07:00"},{"stringValue":"SmJODPpMeeyd8FcfsNsrdYWA"}]}},{"itemRecord":{"value":[{"longValue":"220931945435"},{"stringValue":"New Sealed James Cameron's AVATAR 3D Blu-Ray Panasonic Exclusive PG-13 DVD RARE"},{"moneyValue":{"currencyId":"USD","$t":"61.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"14"},{"longValue":"300"},{"dateValue":"2012-01-19T21:19:51.000-07:00"},{"stringValue":"Sm4H_Y9vXU4EKx-f3wk3EF7A"}]}},{"itemRecord":{"value":[{"longValue":"320829372998"},{"stringValue":"NEW&SEALED 3D Blu-ray Panasonic Exclusive \"AVATAR\" FAST FREE SHIPPING!"},{"moneyValue":{"currencyId":"USD","$t":"89.99"}},{"moneyValue":{"currencyId":"USD","$t":"98.99"}},{"longValue":"0"},{"longValue":["0","399"]},{"dateValue":"2012-01-19T21:53:36.000-07:00"},{"stringValue":"SmcgSHPYl8Y2gPS8cJN-OcrA"}]}},{"itemRecord":{"value":[{"longValue":"190628955236"},{"stringValue":"NEW *Rare* AVATAR Blu-ray 3D Panasonic Exclusive *NOT SOLD IN STORES*"},{"moneyValue":{"currencyId":"USD","$t":"99.99"}},{"moneyValue":{"currencyId":"USD","$t":"109.99"}},{"longValue":"0"},{"longValue":"0"},{"dateValue":"2012-01-20T06:10:25.000-07:00"},{"stringValue":"Sm2CvUgNznvK-l0t-rZ3n4GQ"}]}},{"itemRecord":{"value":[{"longValue":"160718400852"},{"stringValue":"Avatar 3D Blu-Ray Panasonic Exclusive __ Unopened - Original factory shrink wrap"},{"moneyValue":{"currencyId":"USD","$t":"55.01"}},{"moneyValue":{"currencyId":"USD","$t":"75.0"}},{"longValue":"8"},{"longValue":"300"},{"dateValue":"2012-01-20T10:48:32.000-07:00"},{"stringValue":"SmiTg55gmYOWAJ1XbSQ98ECA"}]}},{"itemRecord":{"value":[{"longValue":"130632208352"},{"stringValue":"Avatar 3D Blu-Ray - Panasonic Exclusive (brand new, factory sealed)"},{"moneyValue":{"currencyId":"USD","$t":"62.85"}},{"moneyValue":{"currencyId":"USD","$t":"94.99"}},{"longValue":"12"},{"longValue":"300"},{"dateValue":"2012-01-20T13:52:56.000-07:00"},{"stringValue":"SmtrdC17WyVHvvn_ZgWTXgiA"}]}},{"itemRecord":{"value":[{"longValue":"230733466588"},{"stringValue":"Brand new Avatar 3d blu ray disc. Factory sealed (panasonic exclusive)"},{"moneyValue":{"currencyId":"USD","$t":"50.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"4"},{"longValue":"300"},{"dateValue":"2012-01-20T13:53:56.000-07:00"},{"stringValue":"SmlZdHT_kLO9ggmFSsxS0QCA"}]}},{"itemRecord":{"value":[{"longValue":"320829809050"},{"stringValue":"Avatar 3D Blu-ray Panasonic Exclusive Sealed NEW"},{"moneyValue":{"currencyId":"USD","$t":"60.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"0"},{"longValue":"0"},{"dateValue":"2012-01-20T14:31:02.000-07:00"},{"stringValue":"SmUBlLP2lRLEf0VBWm8ilplg"}]}},{"itemRecord":{"value":[{"longValue":"130630659754"},{"stringValue":"AVATAR 3D Blu-ray Brand New Factory Sealed (Original Panasonic Exclusive)"},{"moneyValue":{"currencyId":"USD","$t":"58.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"15"},{"longValue":"300"},{"dateValue":"2012-01-20T14:34:31.000-07:00"},{"stringValue":"Sm2MdiMGiOAE-0Qh8yDBew4g"}]}},{"itemRecord":{"value":[{"longValue":"150734718107"},{"stringValue":"Avatar 3D Blu-ray Brand New Factory Sealed Panasonic Exclusive"},{"moneyValue":{"currencyId":"USD","$t":"104.99"}},{"moneyValue":{"currencyId":"USD","$t":"104.99"}},{"longValue":"9"},{"longValue":["0","325","1690","-2147481648","16777216"]},{"dateValue":"2012-02-09T17:00:38.000-07:00"},{"stringValue":"SmVD9hFn5o8UG2kBlJRLDI4A"}]}},{"itemRecord":{"value":[{"longValue":"260937482985"},{"stringValue":"BRAND NEW Avatar 3D Blu-Ray DVD - Sealed"},{"moneyValue":{"currencyId":"USD","$t":"70.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"0"},{"longValue":["0","0"]},{"dateValue":"2012-01-20T20:25:55.000-07:00"},{"stringValue":"Smn_b9xfCFZUjdMMzg6b5U_w"}]}},{"itemRecord":{"value":[{"longValue":"120843131441"},{"stringValue":"Avatar 3D blu ray disc factory sealed NIB 3 d version"},{"moneyValue":{"currencyId":"USD","$t":"51.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"3"},{"longValue":"0"},{"dateValue":"2012-01-20T20:30:19.000-07:00"},{"stringValue":"SmRNvQVngyrAAzzicicxqF-g"}]}},{"itemRecord":{"value":[{"longValue":"330673600191"},{"stringValue":"AVATAR 3D Blu Ray-Factory Sealed..FREE Shipping!!!"},{"moneyValue":{"currencyId":"USD","$t":"49.95"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"1"},{"longValue":"0"},{"dateValue":"2012-01-20T21:51:58.000-07:00"},{"stringValue":"SmuX1a85zuIEuO2Jv-BJzp0A"}]}},{"itemRecord":{"value":[{"longValue":"200700624127"},{"stringValue":"AVATAR, 3D, BLU RAY, BRAND NEW AND FACTORY SEALED"},{"moneyValue":{"currencyId":"USD","$t":"50.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"1"},{"longValue":"300"},{"dateValue":"2012-01-20T23:22:51.000-07:00"},{"stringValue":"SmPCqKpN0DBoNqaMNhr3vO9Q"}]}},{"itemRecord":{"value":[{"longValue":"130632758842"},{"stringValue":"3D Avatar Blue Ray Disk"},{"moneyValue":{"currencyId":"USD","$t":"75.0"}},{"moneyValue":{"currencyId":"USD","$t":"90.0"}},{"longValue":"0"},{"longValue":["300","0"]},{"dateValue":"2012-01-21T15:27:37.000-07:00"},{"stringValue":"Smff4598BYjt0QU3hnozg9qQ"}]}},{"itemRecord":{"value":[{"longValue":"180798514647"},{"stringValue":"Avatar Blu-ray 3D Panasonic Exclusive - Sealed NEW"},{"moneyValue":{"currencyId":"USD","$t":"32.93"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"18"},{"longValue":["300","1000"]},{"dateValue":"2012-01-21T15:43:43.000-07:00"},{"stringValue":"Smt8taWyWmsG_Tw-zHfZUmHA"}]}},{"itemRecord":{"value":[{"longValue":"380401406666"},{"stringValue":"AVATAR 3D BLU-RAY MOVIE NEW EDITION --FACTORY SEALED !"},{"moneyValue":{"currencyId":"USD","$t":"95.0"}},{"moneyValue":{"currencyId":"USD","$t":"95.0"}},{"longValue":"11"},{"longValue":"0"},{"dateValue":"2012-02-09T08:43:23.000-07:00"},{"stringValue":"SmipHloK8dVCLobrpiHi9soA"}]}},{"itemRecord":{"value":[{"longValue":"120845197426"},{"stringValue":"Avatar 3D Blu Ray Exlusive Factory Sealed Brand New"},{"moneyValue":{"currencyId":"USD","$t":"70.0"}},{"moneyValue":{"currencyId":"USD","$t":"100.0"}},{"longValue":"1"},{"longValue":"0"},{"dateValue":"2012-01-22T05:35:49.000-07:00"},{"stringValue":"SmSjLcuOvW6zhwC5Lx1h5S-g"}]}},{"itemRecord":{"value":[{"longValue":"320830894431"},{"stringValue":"AVATAR BLU-RAY 3D MOVIE; BRAND NEW, FACTORY SEALED"},{"moneyValue":{"currencyId":"USD","$t":"75.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"0"},{"longValue":"0"},{"dateValue":"2012-01-22T15:55:06.000-07:00"},{"stringValue":"SmE7UPFuIq9m6x9xjY7QFbXg"}]}},{"itemRecord":{"value":[{"longValue":"330672702076"},{"stringValue":"AVATAR 3D BLU-RAY 3D - Brand New Unopened"},{"moneyValue":{"currencyId":"USD","$t":"60.0"}},{"moneyValue":{"currencyId":"USD","$t":"100.0"}},{"longValue":"1"},{"longValue":"300"},{"dateValue":"2012-01-22T16:25:14.000-07:00"},{"stringValue":"SmN_U5mt-bejXAlAg-oekhYg"}]}},{"itemRecord":{"value":[{"longValue":"220933768045"},{"stringValue":"Blue-ray 3D Avatar DVD, Brand New in Original Packaging, Never opened"},{"moneyValue":{"currencyId":"USD","$t":"39.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"8"},{"longValue":"0"},{"dateValue":"2012-01-22T16:58:20.000-07:00"},{"stringValue":"SmZGHJZ-gikK2yYeIDhWxFvQ"}]}},{"itemRecord":{"value":[{"longValue":"170766321061"},{"stringValue":"Avatar 3D blu ray, exclusive Panasonic release. New sealed in hand. Great 3 D"},{"moneyValue":{"currencyId":"USD","$t":"43.99"}},{"moneyValue":{"currencyId":"USD","$t":"85.0"}},{"longValue":"6"},{"longValue":"300"},{"dateValue":"2012-01-22T17:26:33.000-07:00"},{"stringValue":"SmnvAaEh-waB7BW4_CKGWdBQ"}]}},{"itemRecord":{"value":[{"longValue":"300651900316"},{"stringValue":"AVATAR BLU-RAY 3D\"\" PANASONIC EXCLUSIVE NEW SEALED not found in stores"},{"moneyValue":{"currencyId":"USD","$t":"31.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"8"},{"longValue":"300"},{"dateValue":"2012-01-22T18:55:21.000-07:00"},{"stringValue":"SmntGH04Op5W7KLFnYdvAeZA"}]}},{"itemRecord":{"value":[{"longValue":"180798015096"},{"stringValue":"Avatar 3D Blu-ray Panasonic Exclusive, factory sealed, minor box defect."},{"moneyValue":{"currencyId":"USD","$t":"49.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"0"},{"longValue":"0"},{"dateValue":"2012-01-22T19:53:02.000-07:00"},{"stringValue":"SmeZSdGGu_jOcIPVFQpAVQFA"}]}},{"itemRecord":{"value":[{"longValue":"160717564858"},{"stringValue":"Avatar 3D SEALED Blu-ray Panasonic Exclusive"},{"moneyValue":{"currencyId":"USD","$t":"31.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"12"},{"longValue":"0"},{"dateValue":"2012-01-22T20:07:34.000-07:00"},{"stringValue":"SmiWNF8nl9ntob9GViXnyBBA"}]}},{"itemRecord":{"value":[{"longValue":"220932049647"},{"stringValue":"AVATAR 3D BLU-RAY~BRAND NEW~FACTORY SEALED IN SHRINK~PANASONIC PROMO EXCLUSIVE!!"},{"moneyValue":{"currencyId":"USD","$t":"109.99"}},{"moneyValue":{"currencyId":"USD","$t":"120.99"}},{"longValue":"0"},{"longValue":"300"},{"dateValue":"2012-01-22T23:01:04.000-07:00"},{"stringValue":"SmBH2AwKhfOLm0BP7eXlEhNA"}]}},{"itemRecord":{"value":[{"longValue":"180800257998"},{"stringValue":"Avatar Blu-Ray 3D Limited Release Promo Disc - Factory Sealed"},{"moneyValue":{"currencyId":"USD","$t":"89.0"}},{"moneyValue":{"currencyId":"USD","$t":"89.0"}},{"longValue":"0"},{"longValue":"0"},{"dateValue":"2012-01-26T10:27:27.000-07:00"},{"stringValue":"Sm0gVHFWw_MaLbyOMYjwaiog"}]}},{"itemRecord":{"value":[{"longValue":"120844739120"},{"stringValue":"Avatar 3D Blu Ray Factory Sealed Incl. Two 3D Glasses !!"},{"moneyValue":{"currencyId":"USD","$t":"79.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"13"},{"longValue":["0","-2147481148","268435456"]},{"dateValue":"2012-01-23T09:38:20.000-07:00"},{"stringValue":"SmbzRQ-rZ_MKXYvTkoispOVw"}]}},{"itemRecord":{"value":[{"longValue":"140683495269"},{"stringValue":"New AVATAR Blu-ray 3D Panasonic Exclusive *NOT SOLD IN STORES*"},{"moneyValue":{"currencyId":"USD","$t":"32.91"}},{"moneyValue":{"currencyId":"USD","$t":"99.0"}},{"longValue":"2"},{"longValue":"0"},{"dateValue":"2012-01-23T15:02:11.000-07:00"},{"stringValue":"SmZ4iQNLIAiTz0o_0j3bIW9w"}]}},{"itemRecord":{"value":[{"longValue":"170765774879"},{"stringValue":"Avatar 3D Blu-ray Panasonic Exclusive - Not available in stores!"},{"moneyValue":{"currencyId":"USD","$t":"31.93"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"20"},{"longValue":"0"},{"dateValue":"2012-01-23T15:13:47.000-07:00"},{"stringValue":"SmbSQ1lnQYPcCfvpfpvToS8A"}]}},{"itemRecord":{"value":[{"longValue":"180798565141"},{"stringValue":"Avatar 3D Blu-Ray - BRAND NEW and SEALED - Panasonic Exclusive 3 D BluRay"},{"moneyValue":{"currencyId":"USD","$t":"33.93"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"11"},{"longValue":"0"},{"dateValue":"2012-01-23T17:47:14.000-07:00"},{"stringValue":"SmvZYYqQS_evOSt3pDfMno8Q"}]}},{"itemRecord":{"value":[{"longValue":"110810440275"},{"stringValue":"AVATAR 3D Blu-ray Brand New Factory Sealed ñ FREE SHIPPING!"},{"moneyValue":{"currencyId":"USD","$t":"58.99"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"22"},{"longValue":"0"},{"dateValue":"2012-01-23T17:57:52.000-07:00"},{"stringValue":"SmBi99v66zqHKYkKvIAJ9pQA"}]}},{"itemRecord":{"value":[{"longValue":"190628845216"},{"stringValue":"AVATAR 3D Blu-Ray - Panasonic Exclusive - FACTORY SEALED - Free Shipping"},{"moneyValue":{"currencyId":"USD","$t":"31.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"6"},{"longValue":"0"},{"dateValue":"2012-01-23T19:51:19.000-07:00"},{"stringValue":"SmE2rnqwwG4Ox7y9QPAZwmDA"}]}},{"itemRecord":{"value":[{"longValue":"320831486088"},{"stringValue":"Avatar 3D Blu-Ray NEW Factory Sealed - Panasonic Exclusive - FREE SHIPPING"},{"moneyValue":{"currencyId":"USD","$t":"50.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"2"},{"longValue":"0"},{"dateValue":"2012-01-23T21:10:17.000-07:00"},{"stringValue":"Smp2gxOJCJH8Wm7P4n6akm1Q"}]}},{"itemRecord":{"value":[{"longValue":"260937208793"},{"stringValue":"3D Avatar 3D Blu-ray 3D bluray 3D blu ray Brand new sealed NIB new in box"},{"moneyValue":{"currencyId":"USD","$t":"90.0"}},{"moneyValue":{"currencyId":"USD","$t":"120.0"}},{"longValue":"0"},{"longValue":["300","200","500"]},{"dateValue":"2012-01-24T09:58:40.000-07:00"},{"stringValue":"SmKwKZry-47DifBrUXtAjLIA"}]}},{"itemRecord":{"value":[{"longValue":"290659864842"},{"stringValue":"Avatar 3D Blu Ray Panasonic Exclusive Sealed Promo DTS-HD 5.1 Master"},{"moneyValue":{"currencyId":"USD","$t":"26.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"7"},{"longValue":["0","-2147483148","2"]},{"dateValue":"2012-01-24T11:52:45.000-07:00"},{"stringValue":"Smc5ACn355MwQ36-8qVhYJMA"}]}},{"itemRecord":{"value":[{"longValue":"120845375724"},{"stringValue":"Avatar Blu-Ray 3D Panasonic Exclusive Movie Brand New Sealed"},{"moneyValue":{"currencyId":"USD","$t":"80.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"0"},{"longValue":"300"},{"dateValue":"2012-01-24T12:15:28.000-07:00"},{"stringValue":"SmTRKrb5snFcN629amftoz5g"}]}},{"itemRecord":{"value":[{"longValue":"170766323196"},{"stringValue":"Avatar 3D Blu-ray Brand New Factory Sealed"},{"moneyValue":{"currencyId":"USD","$t":"26.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"8"},{"longValue":"0"},{"dateValue":"2012-01-24T17:32:24.000-07:00"},{"stringValue":"Smeip7wxKlFhh3GztuS7jkiA"}]}},{"itemRecord":{"value":[{"longValue":"220936324950"},{"stringValue":"AVATAR 3D BLU-RAY~BRAND NEW~FACTORY SEALED IN SHRINK~PANASONIC PROMO EXCLUSIVE!!"},{"moneyValue":{"currencyId":"USD","$t":"89.99"}},{"moneyValue":{"currencyId":"USD","$t":"99.99"}},{"longValue":"0"},{"longValue":"300"},{"dateValue":"2012-01-24T18:15:10.000-07:00"},{"stringValue":"Sm_JHQtAx3TZEDGP0Lw6ObpA"}]}},{"itemRecord":{"value":[{"longValue":"320831969924"},{"stringValue":"AVATAR 3D Blu Ray (Original Panasonic Exclusive) - Like NEW"},{"moneyValue":{"currencyId":"USD","$t":"40.0"}},{"moneyValue":{"currencyId":"USD","$t":"86.0"}},{"longValue":"1"},{"longValue":"300"},{"dateValue":"2012-01-24T20:26:55.000-07:00"},{"stringValue":"Smnzp3FhNin5GcqoftqekADg"}]}},{"itemRecord":{"value":[{"longValue":"150738091689"},{"stringValue":"New RARE Avatar Blu-ray Blu Ray 3-D 3 D Panasonic Exclusive NOT SOLD IN STORES"},{"moneyValue":{"currencyId":"USD","$t":"199.99"}},{"moneyValue":{"currencyId":"USD","$t":"199.99"}},{"longValue":"0"},{"longValue":["0","-2147482303","268435456","-2147480098","268435456"]},{"dateValue":"2012-01-22T16:26:56.000-07:00"},{"stringValue":"SmuB9oGX7_insOHm5Wm1mtPA"}]}},{"itemRecord":{"value":[{"longValue":"200697624093"},{"stringValue":"New Avatar 3D Blu-Ray Panasonic Exclusive Factory Sealed New"},{"moneyValue":{"currencyId":"USD","$t":"105.0"}},{"moneyValue":{"currencyId":"USD","$t":"105.0"}},{"longValue":"1"},{"longValue":["0","0"]},{"dateValue":"2012-02-06T13:17:53.000-07:00"},{"stringValue":"Sm4Ih4QKzC5nfe3TenzzSiSA"}]}},{"itemRecord":{"value":[{"longValue":"320832354417"},{"stringValue":"Avatar 3-d Blu Ray With Sony Blu Ray Player"},{"moneyValue":{"currencyId":"USD","$t":"150.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"0"},{"longValue":"300"},{"dateValue":"2012-01-25T12:33:27.000-07:00"},{"stringValue":"SmQ-meY-Gw-I--dGgWe4aNdA"}]}},{"itemRecord":{"value":[{"longValue":"320832387656"},{"stringValue":"James Cameron's AVATAR Exclusive Blu-Ray 3D **FACTORY SEALED**"},{"moneyValue":{"currencyId":"USD","$t":"85.0"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"0"},{"longValue":"0"},{"dateValue":"2012-01-25T13:20:30.000-07:00"},{"stringValue":"Sm-_Y6j0vHctWYksalN84VFw"}]}},{"itemRecord":{"value":[{"longValue":"320832469688"},{"stringValue":"Avatar Blu-ray 3D"},{"moneyValue":{"currencyId":"USD","$t":"39.99"}},{"moneyValue":{"currencyId":"USD","$t":"0.0"}},{"longValue":"0"},{"longValue":"241"},{"dateValue":"2012-01-25T16:09:30.000-07:00"},{"stringValue":"Sme85gcM76LwgS-iccLJrT7g"}]}},{"itemRecord":{"value":[{"longValue":"110811394468"},{"stringValue":"NEW- AVATAR 3D Blu-Ray Movie- PANASONIC EXCLUSIVE&FACTORY SEALED!!"},{"moneyValue":{"currencyId":"USD","$t":"31.0"}},{"moneyValue":{"currencyId":"USD","$t":"95.0"}},{"longValue":"3"},{"longValue":"0"},{"dateValue":"2012-01-25T20:47:13.000-07:00"},{"stringValue":"Sml7KjYSTL-Pw446Zcx9UrNw"}]}},{"itemRecord":{"value":[{"longValue":"190629134325"},{"stringValue":"AVATAR 3D BLU-RAY DISC Panasonic Exclusive, Factory Sealed Dolby Digital DTS-HD"},{"moneyValue":{"currencyId":"USD","$t":"104.95"}},{"moneyValue":{"currencyId":"USD","$t":"104.95"}},{"longValue":"0"},{"longValue":"0"},{"dateValue":"2012-02-16T17:03:33.000-07:00"},{"stringValue":"SmDZ8RlMIjDvlEW3KUibzj2Q"}]}}],"dfnResponse":{"productTypeCoverage":{"name":"US_DVD_HD_DVD_Blu_ray","supplyScore":"108.0","demandScore":"100.0","aggregateScore":"90.24579692259518"}},"queryTime":"157","executionTime":"204","backendTestResponse":{}}}}} \ No newline at end of file diff --git a/test/fixtures/large.xml b/test/fixtures/large.xml new file mode 100644 index 0000000..fe3b720 --- /dev/null +++ b/test/fixtures/large.xml @@ -0,0 +1,1132 @@ + + + +Success +1.1.0 +2012-01-20T01:36:25.904Z + + 3 + 1.0.0 + text/html + <a>qds=0.1723&!_dcat_leaf=617,163826,617,163826,15077&pct=94.84&nai=44&nhalf=0&ncbt=0&nmq=2&!SIBE=avatar+blue+ray+3d,JPIA9PMIDQ8:7M&auctions=44&nbi=22&iat=4&trsi=0&prof=5841&nabi=16&fixedprices=4&!ptrid=Pr1062_10,Pr5841_2&pcc=2&nProdSur=2&tcatid=617</a> + + + 118 + 113 + 2012-01-19T18:36:02.000-07:00 + + + + + 81996414 + + + Avatar (DVD, 2010) + + + 78 + + 4.0 + + + + 2012-01-19T21:01:14 + + 13.5 + + + + 34 + +3.96 + + +44 + + + http://i.ebayimg.com/22/!!d7WiF!EWM~$(KGrHqMOKikEvOnbKY1gBL9fO1lupQ~~_6.JPG?set_id=89040003C1 + + + + + 82093597 + + + Avatar (Blu-ray/DVD, 2010, 2-Disc Set) + + + 74 + + 15.01 + + + + 2012-01-19T19:12:15 + +20.0 + + +26 +11.96 + +48 + + + http://i.ebayimg.com/01/!!d8dfeQ!mM~$(KGrHqUOKjcEwhzOMI3VBMSIdcD!Yw~~_6.JPG?set_id=89040003C1 + + + + + 220931734658 + + + AVATAR 3D BLU-RAY FACTORY SEALED -new,sealed- + + 70.99 + + +79.99 + + +1 + +300 + +2012-01-19T19:15:14.000-07:00 + +Sm86FNl5NfYQDIhtWAUiWbqQ + + + + 170763800829 + + + Avatar 3D Blu-ray Disc - BRAND NEW - FACTORY SEALED - PANASONIC EXCLUSIVE + + + 61.0 + + +74.99 + + +4 + +300 +0 + +2012-01-19T19:51:57.000-07:00 + +SmJODPpMeeyd8FcfsNsrdYWA + + + + 220931945435 + + + New Sealed James Cameron's AVATAR 3D Blu-Ray Panasonic Exclusive PG-13 DVD RARE + + + 61.0 + + +0.0 + + +14 + +300 + +2012-01-19T21:19:51.000-07:00 + +Sm4H_Y9vXU4EKx-f3wk3EF7A + + + + 320829372998 + + + NEW & SEALED 3D Blu-ray Panasonic Exclusive "AVATAR" FAST FREE SHIPPING! + + + 89.99 + + +98.99 + + +0 + +0 +399 + +2012-01-19T21:53:36.000-07:00 + +SmcgSHPYl8Y2gPS8cJN-OcrA + + + + 190628955236 + + + NEW *Rare* AVATAR Blu-ray 3D Panasonic Exclusive *NOT SOLD IN STORES* + + 99.99 + + +109.99 + + +0 + +0 + +2012-01-20T06:10:25.000-07:00 + +Sm2CvUgNznvK-l0t-rZ3n4GQ + + + + 160718400852 + + + Avatar 3D Blu-Ray Panasonic Exclusive __ Unopened - Original factory shrink wrap + + + 55.01 + + +75.0 + + +8 + +300 + +2012-01-20T10:48:32.000-07:00 + +SmiTg55gmYOWAJ1XbSQ98ECA + + + + 130632208352 + + + Avatar 3D Blu-Ray - Panasonic Exclusive (brand new, factory sealed) + + 62.85 + + +94.99 + + +12 + +300 + +2012-01-20T13:52:56.000-07:00 + +SmtrdC17WyVHvvn_ZgWTXgiA + + + + 230733466588 + + + Brand new Avatar 3d blu ray disc. Factory sealed (panasonic exclusive) + + + 50.0 + + +0.0 + + +4 + +300 + +2012-01-20T13:53:56.000-07:00 + +SmlZdHT_kLO9ggmFSsxS0QCA + + + + 320829809050 + + + Avatar 3D Blu-ray Panasonic Exclusive Sealed NEW + + 60.0 + + +0.0 + + +0 + +0 + +2012-01-20T14:31:02.000-07:00 + +SmUBlLP2lRLEf0VBWm8ilplg + + + + 130630659754 + + + AVATAR 3D Blu-ray Brand New Factory Sealed (Original Panasonic Exclusive) + + + 58.0 + + +0.0 + + +15 + +300 + +2012-01-20T14:34:31.000-07:00 + +Sm2MdiMGiOAE-0Qh8yDBew4g + + + + 150734718107 + + + Avatar 3D Blu-ray Brand New Factory Sealed Panasonic Exclusive + + 104.99 + + +104.99 + + +9 + +0 +325 +1690 +-2147481648 +16777216 + +2012-02-09T17:00:38.000-07:00 + +SmVD9hFn5o8UG2kBlJRLDI4A + + + + 260937482985 + + + BRAND NEW Avatar 3D Blu-Ray DVD - Sealed + + 70.0 + + +0.0 + + +0 + +0 +0 + +2012-01-20T20:25:55.000-07:00 + +Smn_b9xfCFZUjdMMzg6b5U_w + + + + 120843131441 + + + Avatar 3D blu ray disc factory sealed NIB 3 d version + + 51.0 + + +0.0 + + +3 + +0 + +2012-01-20T20:30:19.000-07:00 + +SmRNvQVngyrAAzzicicxqF-g + + + + 330673600191 + + + AVATAR 3D Blu Ray-Factory Sealed..FREE Shipping!!! + + 49.95 + + +0.0 + + +1 + +0 + +2012-01-20T21:51:58.000-07:00 + +SmuX1a85zuIEuO2Jv-BJzp0A + + + + 200700624127 + + + AVATAR, 3D, BLU RAY, BRAND NEW AND FACTORY SEALED + + 50.0 + + +0.0 + + +1 + +300 + +2012-01-20T23:22:51.000-07:00 + +SmPCqKpN0DBoNqaMNhr3vO9Q + + + + 130632758842 + + + 3D Avatar Blue Ray Disk + + 75.0 + + +90.0 + + +0 + +300 +0 + +2012-01-21T15:27:37.000-07:00 + +Smff4598BYjt0QU3hnozg9qQ + + + + 180798514647 + + + Avatar Blu-ray 3D Panasonic Exclusive - Sealed NEW + + 32.93 + + +0.0 + + +18 + +300 +1000 + +2012-01-21T15:43:43.000-07:00 + +Smt8taWyWmsG_Tw-zHfZUmHA + + + + 380401406666 + + + AVATAR 3D BLU-RAY MOVIE NEW EDITION --FACTORY SEALED ! + + 95.0 + + +95.0 + + +11 + +0 + +2012-02-09T08:43:23.000-07:00 + +SmipHloK8dVCLobrpiHi9soA + + + + 120845197426 + + + Avatar 3D Blu Ray Exlusive Factory Sealed Brand New + + 70.0 + + +100.0 + + +1 + +0 + +2012-01-22T05:35:49.000-07:00 + +SmSjLcuOvW6zhwC5Lx1h5S-g + + + + 320830894431 + + + AVATAR BLU-RAY 3D MOVIE; BRAND NEW, FACTORY SEALED + + 75.0 + + +0.0 + + +0 + +0 + +2012-01-22T15:55:06.000-07:00 + +SmE7UPFuIq9m6x9xjY7QFbXg + + + + 330672702076 + + + AVATAR 3D BLU-RAY 3D - Brand New Unopened + + 60.0 + + +100.0 + + +1 + +300 + +2012-01-22T16:25:14.000-07:00 + +SmN_U5mt-bejXAlAg-oekhYg + + + + 220933768045 + + + Blue-ray 3D Avatar DVD, Brand New in Original Packaging, Never opened + + 39.0 + + +0.0 + + +8 + +0 + +2012-01-22T16:58:20.000-07:00 + +SmZGHJZ-gikK2yYeIDhWxFvQ + + + + 170766321061 + + + Avatar 3D blu ray, exclusive Panasonic release. New sealed in hand. Great 3 D + + + 43.99 + + +85.0 + + +6 + +300 + +2012-01-22T17:26:33.000-07:00 + +SmnvAaEh-waB7BW4_CKGWdBQ + + + + 300651900316 + + + AVATAR BLU-RAY 3D"" PANASONIC EXCLUSIVE NEW SEALED not found in stores + + + 31.0 + + +0.0 + + +8 + +300 + +2012-01-22T18:55:21.000-07:00 + +SmntGH04Op5W7KLFnYdvAeZA + + + + 180798015096 + + + Avatar 3D Blu-ray Panasonic Exclusive, factory sealed, minor box defect. + + + 49.0 + + +0.0 + + +0 + +0 + +2012-01-22T19:53:02.000-07:00 + +SmeZSdGGu_jOcIPVFQpAVQFA + + + + 160717564858 + + + Avatar 3D SEALED Blu-ray Panasonic Exclusive + + 31.0 + + +0.0 + + +12 + +0 + +2012-01-22T20:07:34.000-07:00 + +SmiWNF8nl9ntob9GViXnyBBA + + + + 220932049647 + + + AVATAR 3D BLU-RAY~BRAND NEW~FACTORY SEALED IN SHRINK~PANASONIC PROMO EXCLUSIVE!! + + + 109.99 + + +120.99 + + +0 + +300 + +2012-01-22T23:01:04.000-07:00 + +SmBH2AwKhfOLm0BP7eXlEhNA + + + + 180800257998 + + + Avatar Blu-Ray 3D Limited Release Promo Disc - Factory Sealed + + 89.0 + + +89.0 + + +0 + +0 + +2012-01-26T10:27:27.000-07:00 + +Sm0gVHFWw_MaLbyOMYjwaiog + + + + 120844739120 + + + Avatar 3D Blu Ray Factory Sealed Incl. Two 3D Glasses !! + + 79.0 + + +0.0 + + +13 + +0 +-2147481148 +268435456 + +2012-01-23T09:38:20.000-07:00 + +SmbzRQ-rZ_MKXYvTkoispOVw + + + + 140683495269 + + + New AVATAR Blu-ray 3D Panasonic Exclusive *NOT SOLD IN STORES* + + 32.91 + + +99.0 + + +2 + +0 + +2012-01-23T15:02:11.000-07:00 + +SmZ4iQNLIAiTz0o_0j3bIW9w + + + + 170765774879 + + + Avatar 3D Blu-ray Panasonic Exclusive - Not available in stores! + + 31.93 + + +0.0 + + +20 + +0 + +2012-01-23T15:13:47.000-07:00 + +SmbSQ1lnQYPcCfvpfpvToS8A + + + + 180798565141 + + + Avatar 3D Blu-Ray - BRAND NEW and SEALED - Panasonic Exclusive 3 D BluRay + + + 33.93 + + +0.0 + + +11 + +0 + +2012-01-23T17:47:14.000-07:00 + +SmvZYYqQS_evOSt3pDfMno8Q + + + + 110810440275 + + + AVATAR 3D Blu-ray Brand New Factory Sealed ñ FREE SHIPPING! + + 58.99 + + +0.0 + + +22 + +0 + +2012-01-23T17:57:52.000-07:00 + +SmBi99v66zqHKYkKvIAJ9pQA + + + + 190628845216 + + + AVATAR 3D Blu-Ray - Panasonic Exclusive - FACTORY SEALED - Free Shipping + + + 31.0 + + +0.0 + + +6 + +0 + +2012-01-23T19:51:19.000-07:00 + +SmE2rnqwwG4Ox7y9QPAZwmDA + + + + 320831486088 + + + Avatar 3D Blu-Ray NEW Factory Sealed - Panasonic Exclusive - FREE SHIPPING + + + 50.0 + + +0.0 + + +2 + +0 + +2012-01-23T21:10:17.000-07:00 + +Smp2gxOJCJH8Wm7P4n6akm1Q + + + + 260937208793 + + + 3D Avatar 3D Blu-ray 3D bluray 3D blu ray Brand new sealed NIB new in box + + + 90.0 + + +120.0 + + +0 + +300 +200 +500 + +2012-01-24T09:58:40.000-07:00 + +SmKwKZry-47DifBrUXtAjLIA + + + + 290659864842 + + + Avatar 3D Blu Ray Panasonic Exclusive Sealed Promo DTS-HD 5.1 Master + + 26.0 + + +0.0 + + +7 + +0 +-2147483148 +2 + +2012-01-24T11:52:45.000-07:00 + +Smc5ACn355MwQ36-8qVhYJMA + + + + 120845375724 + + + Avatar Blu-Ray 3D Panasonic Exclusive Movie Brand New Sealed + + 80.0 + + +0.0 + + +0 + +300 + +2012-01-24T12:15:28.000-07:00 + +SmTRKrb5snFcN629amftoz5g + + + + 170766323196 + + + Avatar 3D Blu-ray Brand New Factory Sealed + + 26.0 + + +0.0 + + +8 + +0 + +2012-01-24T17:32:24.000-07:00 + +Smeip7wxKlFhh3GztuS7jkiA + + + + 220936324950 + + + AVATAR 3D BLU-RAY~BRAND NEW~FACTORY SEALED IN SHRINK~PANASONIC PROMO EXCLUSIVE!! + + + 89.99 + + +99.99 + + +0 + +300 + +2012-01-24T18:15:10.000-07:00 + +Sm_JHQtAx3TZEDGP0Lw6ObpA + + + + 320831969924 + + + AVATAR 3D Blu Ray (Original Panasonic Exclusive) - Like NEW + + 40.0 + + +86.0 + + +1 + +300 + +2012-01-24T20:26:55.000-07:00 + +Smnzp3FhNin5GcqoftqekADg + + + + 150738091689 + + + New RARE Avatar Blu-ray Blu Ray 3-D 3 D Panasonic Exclusive NOT SOLD IN STORES + + + 199.99 + + +199.99 + + +0 + +0 +-2147482303 +268435456 +-2147480098 +268435456 + +2012-01-22T16:26:56.000-07:00 + +SmuB9oGX7_insOHm5Wm1mtPA + + + + 200697624093 + + + New Avatar 3D Blu-Ray Panasonic Exclusive Factory Sealed New + + 105.0 + + +105.0 + + +1 + +0 +0 + +2012-02-06T13:17:53.000-07:00 + +Sm4Ih4QKzC5nfe3TenzzSiSA + + + + 320832354417 + + + Avatar 3-d Blu Ray With Sony Blu Ray Player + + 150.0 + + +0.0 + + +0 + +300 + +2012-01-25T12:33:27.000-07:00 + +SmQ-meY-Gw-I--dGgWe4aNdA + + + + 320832387656 + + + James Cameron's AVATAR Exclusive Blu-Ray 3D **FACTORY SEALED** + + 85.0 + + +0.0 + + +0 + +0 + +2012-01-25T13:20:30.000-07:00 + +Sm-_Y6j0vHctWYksalN84VFw + + + + 320832469688 + + + Avatar Blu-ray 3D + + 39.99 + + +0.0 + + +0 + +241 + +2012-01-25T16:09:30.000-07:00 + +Sme85gcM76LwgS-iccLJrT7g + + + + 110811394468 + + + NEW- AVATAR 3D Blu-Ray Movie- PANASONIC EXCLUSIVE & FACTORY SEALED!! + + + 31.0 + + +95.0 + + +3 + +0 + +2012-01-25T20:47:13.000-07:00 + +Sml7KjYSTL-Pw446Zcx9UrNw + + + + 190629134325 + + + AVATAR 3D BLU-RAY DISC Panasonic Exclusive, Factory Sealed Dolby Digital DTS-HD + + + 104.95 + + +104.95 + + +0 + +0 + +2012-02-16T17:03:33.000-07:00 + +SmDZ8RlMIjDvlEW3KUibzj2Q + + + US_DVD_HD_DVD_Blu_ray + 108.0 + 100.0 + 90.24579692259518 + +157204 + \ No newline at end of file diff --git a/test/fixtures/reorder.json b/test/fixtures/reorder.json new file mode 100644 index 0000000..2ba0f61 --- /dev/null +++ b/test/fixtures/reorder.json @@ -0,0 +1 @@ +{"parent":{"parent_property":"bar","child":{"child_property":"foo"}}} \ No newline at end of file diff --git a/test/fixtures/reorder.xml b/test/fixtures/reorder.xml new file mode 100644 index 0000000..4e68960 --- /dev/null +++ b/test/fixtures/reorder.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/fixtures/spacetext.json b/test/fixtures/spacetext.json new file mode 100644 index 0000000..152789c --- /dev/null +++ b/test/fixtures/spacetext.json @@ -0,0 +1 @@ +{"doc":{"Column":[{"Name":"shit","Value":{"type":"STRING","$t":" abc\nasdf\na "}},{"Name":"foo","Value":{"type":"STRING"}},{"Name":"foo2","Value":{"type":"STRING"}},{"Name":"bar","Value":{"type":"STRING","$t":" "}},{"PK":"true","Name":"uid","Value":{"type":"STRING","$t":"god"}}]}} \ No newline at end of file diff --git a/test/fixtures/spacetext.xml b/test/fixtures/spacetext.xml new file mode 100644 index 0000000..f1c61f7 --- /dev/null +++ b/test/fixtures/spacetext.xml @@ -0,0 +1,14 @@ + + + shit + abc +asdf +a + + + foo + foo2 + bar + uidgod + + diff --git a/test/test-coerce.js b/test/test-coerce.js new file mode 100644 index 0000000..363230e --- /dev/null +++ b/test/test-coerce.js @@ -0,0 +1,22 @@ +var fs = require('fs'); +var parser = require('../lib'); +var assert = require('assert'); + +var file = __dirname + '/fixtures/coerce.xml'; + +var data = fs.readFileSync(file); + +// With coercion +var result = parser.toJson(data, {reversible: true, coerce: true, object: true}); +console.log(result.itemRecord.value); +assert.strictEqual(result.itemRecord.value[0].longValue['$t'], 12345); +assert.strictEqual(result.itemRecord.value[1].stringValue.number, false); +assert.strictEqual(result.itemRecord.value[2].moneyValue.number, true); +assert.strictEqual(result.itemRecord.value[2].moneyValue['$t'], 104.95); + +// Without coercion +result = parser.toJson(data, {reversible: true, coerce: false, object: true}); +assert.strictEqual(result.itemRecord.value[0].longValue['$t'], '12345'); +assert.strictEqual(result.itemRecord.value[1].stringValue.number, 'false'); +assert.strictEqual(result.itemRecord.value[2].moneyValue.number, 'true'); +assert.strictEqual(result.itemRecord.value[2].moneyValue['$t'], '104.95'); \ No newline at end of file diff --git a/test/test-reorder.js b/test/test-reorder.js new file mode 100644 index 0000000..12f5d80 --- /dev/null +++ b/test/test-reorder.js @@ -0,0 +1,18 @@ +var fs = require('fs'); +var path = require('path'); +var parser = require('../lib'); +var assert = require('assert'); + +var data = fs.readFileSync('./fixtures/reorder.json'); +var result = parser.toXml(data); +console.log(result); + +var expected = fs.readFileSync('./fixtures/reorder.xml') + ''; + +if (expected) { + expected = expected.trim(); +} + +//console.log(result + '<---'); +assert.deepEqual(result, expected, 'reorder.json and reorder.xml are different'); +console.log('[json2xml: reoder.json -> roerder.xml] passed!'); diff --git a/test/test-space.js b/test/test-space.js new file mode 100644 index 0000000..e4a1bd7 --- /dev/null +++ b/test/test-space.js @@ -0,0 +1,25 @@ +var fs = require('fs'); +var path = require('path'); +var parser = require('../lib'); +var assert = require('assert'); + +var xml = fs.readFileSync(__dirname + '/fixtures/spacetext.xml'); +var json = parser.toJson(xml, {object: true, space: true}); +console.log('xml => json: \n%j', json); + +console.log('---------------------\njson => xml: \n%j\n', + parser.toXml(fs.readFileSync(__dirname + '/fixtures/spacetext.json'))); +function eql(a, b) { + for (var k in a) { + assert.deepEqual(a[k], b[k], JSON.stringify(a) + ' should equal ' + JSON.stringify(b)); + } +} + +assert.deepEqual(json.doc.Column.length, 5, 'should have 5 Columns'); +eql(json.doc.Column[0], {Name: 'shit', Value: {type: 'STRING', $t: ' abc\nasdf\na '}}); +eql(json.doc.Column[1], {Name: 'foo', Value: {type: 'STRING'}}); +eql(json.doc.Column[2], {Name: 'foo2', Value: {type: 'STRING'}}); +eql(json.doc.Column[3], {Name: 'bar', Value: {type: 'STRING', $t: ' '}}); +eql(json.doc.Column[4], {PK: 'true', Name: 'uid', Value: {type: 'STRING', $t: 'god'}}); + +console.log('xml2json options.space passed!'); diff --git a/test/test.js b/test/test.js index f533bfe..02a2449 100644 --- a/test/test.js +++ b/test/test.js @@ -6,62 +6,86 @@ var assert = require('assert'); var fixturesPath = './fixtures'; fs.readdir(fixturesPath, function(err, files) { - for (var i in files) { - var file = files[i]; - var ext = path.extname(file); + for (var i in files) { + var file = files[i]; + var ext = path.extname(file); - if (ext == '.xml') { - var basename = path.basename(file, '.xml'); + if (ext == '.xml') { + var basename = path.basename(file, '.xml'); - var data = fs.readFileSync(fixturesPath + '/' + file); - var result = parser.toJson(data, {reversible: true}); + var data = fs.readFileSync(fixturesPath + '/' + file); + var result = parser.toJson(data, {reversible: true}); - var data2 = fs.readFileSync(fixturesPath + '/' + file); - result = parser.toJson(data2); + var data2 = fs.readFileSync(fixturesPath + '/' + file); + if (file.indexOf('spacetext') >= 0) { + result = parser.toJson(data2, {trim: false, coerce: false}); + } else if (file.indexOf('coerce') >= 0) { + result = parser.toJson(data2, {coerce: false}); + } else if (file.indexOf('domain') >= 0) { + result = parser.toJson(data2, {coerce: false}); + } else if (file.indexOf('large') >= 0) { + result = parser.toJson(data2, {coerce: false, trim: true, sanitize: false}); + } else if (file.indexOf('entities') >= 0) { +/* + console.log('XML ================================================== XML'); + console.log(file,':'); + console.log(data); + console.log('--------------------------------------------------'); + console.log(result); +*/ + result = parser.toJson(data2, {trim: false, reversible: true, sanitize: true}); +/* + console.log('XML ================================================== '); + console.log(data2); + console.log('--------------------------------------------------'); + console.log(result); +*/ + } else { + result = parser.toJson(data2, {trim: false}); + } - var jsonFile = basename + '.json'; - var expected = fs.readFileSync(fixturesPath + '/' + jsonFile) + ''; + var jsonFile = basename + '.json'; + var expected = fs.readFileSync(fixturesPath + '/' + jsonFile) + ''; - if (expected) { - expected = expected.trim(); - } - assert.deepEqual(result, expected, jsonFile + ' and ' + file + ' are different'); - console.log('[xml2json: ' + file + '->' + jsonFile + '] passed!'); - } else if( ext == '.json') { - var basename = path.basename(file, '.json'); - if (basename.match('reversible')) { - var data = fs.readFileSync(fixturesPath + '/' + file); - var result = parser.toXml(data); - - var xmlFile = basename.split('-')[0] + '.xml'; - var expected = fs.readFileSync(fixturesPath + '/' + xmlFile) + ''; - - if (expected) { - expected = expected.trim(); - } - //console.log(result + '<---'); - assert.deepEqual(result, expected, xmlFile + ' and ' + file + ' are different'); - console.log('[json2xml: ' + file + '->' + xmlFile + '] passed!'); - } - } - } -}); - -// test options.textNodeKey custom value -var xml = 'Example Site'; -var actual = parser.toJson(xml, {object: true, textNodeKey: 'hi'}); -var json = '{"a":{"href":"http://example.com","hi":"Example Site"}}'; -assert.deepEqual(actual, JSON.parse(json)); + if (expected) { + expected = expected.trim(); + } +/* + console.log('>>>>>>>>>>>>> ============ Result =============== <<<<<<<<<<<<<<<<'); + console.log(result); + console.log('>>>>>>>>>>>>> ============ Expected =============== <<<<<<<<<<<<<<<<'); + console.log(expected) +*/ + assert.deepEqual(result, expected, jsonFile + ' and ' + file + ' are different'); + console.log('[xml2json: ' + file + '->' + jsonFile + '] passed!'); + } else if( ext == '.json') { + var basename = path.basename(file, '.json'); + if (basename.match('reversible')) { + var data = fs.readFileSync(fixturesPath + '/' + file); + var result = parser.toXml(data); + + var xmlFile = basename.split('-')[0] + '.xml'; + var expected = fs.readFileSync(fixturesPath + '/' + xmlFile) + ''; -// test options.textNodeKey default value -var actual = parser.toJson(xml, {object: true}); -var json = json.replace('"hi":', '"$t":'); -assert.deepEqual(actual, JSON.parse(json)); + console.log(' ') + console.log('===JSON==================================================JSON===') + console.log(file,':') + console.log('---data-----------------------------------------------') + console.log(data) + console.log('---result-----------------------------------------------') + console.log(result) + console.log(' ') -console.log('[xml2json options.textNodeKey] passed'); + if (expected) { + expected = expected.trim(); + } + console.log('---expected-----------------------------------------------'); + console.log(expected); + //console.log(result + '<---'); + assert.deepEqual(result, expected, xmlFile + ' and ' + file + ' are different'); + console.log('[json2xml: ' + file + '->' + xmlFile + '] passed!'); + } + } + } +}); -// test options.attributes = false -var actual = parser.toJson(xml, {object: true, attributes: false}); -var json = '{"a": "Example Site"}' -assert.deepEqual(actual, JSON.parse(json)); -console.log('[xml2json options.attributes] passed');