+105
| var sax = require("sax"); | ||
| exports.read = function(xmlstring, callback){ | ||
| var saxparser = sax.parser(true); | ||
| var rootobject = {}; | ||
| var object = rootobject; | ||
| saxparser.onerror = function (err) { | ||
| // an error happened. | ||
| return callback(err); | ||
| }; | ||
| saxparser.onopentag = function (node) { | ||
| // opened a tag. node has "name" and "attributes" | ||
| // create a new object and fill it with a function that returns the attributes: | ||
| var newobject = { | ||
| attributes: function(name){ | ||
| return node.attributes; | ||
| } | ||
| }; | ||
| addGetParentFunction(newobject, object); | ||
| // add 2 functions to the object so that the object can be accessed as if it was an array: | ||
| addGetLengthFunction(newobject); | ||
| addAtFunction(newobject); | ||
| if(object[node.name]){ | ||
| // we're dealing with objects of the same name, let's wrap them in an array | ||
| // check if there's already an array: | ||
| if(!object[node.name].array){ | ||
| // no array, create one and at itself + newobject: | ||
| var firstobject = object[node.name]; | ||
| object[node.name] = {}; | ||
| object[node.name].array = new Array(firstobject, newobject); | ||
| }else{ | ||
| // alreay an array, just add the newobject to it: | ||
| object[node.name].array.push(newobject); | ||
| } | ||
| // add 2 functions to work with that array: | ||
| addGetLengthFunction(object[node.name]); | ||
| addAtFunction(object[node.name]); | ||
| }else{ | ||
| // we're dealing with simple objects, no array: | ||
| object[node.name] = newobject; | ||
| } | ||
| // set the current object to the newobject: | ||
| object = newobject; | ||
| }; | ||
| saxparser.ontext = function (text) { | ||
| object.text = function(){ | ||
| return text; | ||
| } | ||
| }; | ||
| saxparser.onclosetag = function (node) { | ||
| object = object.getParent(); | ||
| } | ||
| saxparser.onend = function () { | ||
| return callback(null, rootobject); | ||
| }; | ||
| // We need closures for this: | ||
| function addGetLengthFunction(object){ | ||
| if(object.array){ | ||
| object.getLength = function(){ | ||
| return object.array.length; | ||
| } | ||
| }else{ | ||
| object.getLength = function(){ | ||
| return 1; | ||
| } | ||
| } | ||
| } | ||
| function addAtFunction(object){ | ||
| if(object.array){ | ||
| object.at = function(index){ | ||
| return object.array[index]; | ||
| } | ||
| }else{ | ||
| object.at = function(index){ | ||
| return object; | ||
| } | ||
| } | ||
| } | ||
| function addGetParentFunction(object, parent){ | ||
| object.getParent = function(){ | ||
| return parent; | ||
| } | ||
| } | ||
| saxparser.write(xmlstring).close(); | ||
| } |
+2
-2
| { | ||
| "name": "xmlreader", | ||
| "description": "node library to read xml the easy way", | ||
| "version": "0.0.1", | ||
| "version": "0.1.0", | ||
| "author": { | ||
@@ -16,3 +16,3 @@ "name": "Sam Decrock", | ||
| }, | ||
| "main": "./xml", | ||
| "main": "./xmlreader", | ||
| "licenses": [ | ||
@@ -19,0 +19,0 @@ { |
+64
-1
| node-xmlreader | ||
| ============== | ||
| An xml reader for node that uses a different approach than all other xml readers/parsers out there | ||
| An xml reader for node that uses a different approach than all other xml readers/parsers out there. | ||
| ## Install | ||
| You can install xmlreader using the Node Package Manager (npm): | ||
| npm install xmlreader | ||
| ## Introduction ## | ||
| I wanted a xml reader that's easy to use and that doesn't require tricks to access the attributes and text values of xml-nodes. Most xml parsers out there use some kind of prefix, but that's not a sound solution. | ||
| I'm using functions to differentiate the attributes and text from the nodes: | ||
| ``` node.attributes() ``` and ``` node.text() ``` | ||
| I also wanted a xml parser that can handle multiple nodes of the same name. Most parsers out there just ignore those or threat every node as an array. | ||
| I'm using functions to get to nodes of the same name. The same functions can also be used to get to nodes where there's only one of them: | ||
| ``` nodes.getLength() ``` and ``` nodes.at(1) ``` | ||
| ## Example ## | ||
| ```js | ||
| var xmlreader = require('xmlreader'); | ||
| var someXml = '<response id="1" shop="aldi">' | ||
| + 'This is some other content' | ||
| + '<who name="james">James May</who>' | ||
| + '<who name="sam">' | ||
| + 'Sam Decrock' | ||
| + '<location>Belgium</location>' | ||
| + '</who>' | ||
| + '<who name="jack">Jack Johnsen</who>' | ||
| + '<games age="6">' | ||
| + '<game>Some great game</game>' | ||
| + '<game>Some other great game</game>' | ||
| + '</games>' | ||
| + '<notes>These are some notes</notes>' | ||
| + '</response>' | ||
| xmlreader.read(someXml, function (err, res){ | ||
| // use .text() to get the content of a node: | ||
| console.log( res.response.text() ); | ||
| // use .attributes() to get the attributes of a node: | ||
| console.log( res.response.attributes().shop ); | ||
| console.log(""); | ||
| // using the getLength() and the at() function, you can loop through nodes with the same name: | ||
| for(var i = 0; i < res.response.who.getLength(); i++){ | ||
| console.log( res.response.who.at(i).text() ); | ||
| } | ||
| console.log( res.response.who.at(1).text() ) ; | ||
| console.log( res.response.who.at(1).location.text() ); | ||
| // you can also get regular nodes like you get arrays: | ||
| console.log( res.response.notes.at(0).text() ); | ||
| }); | ||
| ``` |
+30
-41
@@ -1,49 +0,38 @@ | ||
| var sax = require("sax"), | ||
| strict = true, // set to false for html-mode | ||
| parser = sax.parser(strict); | ||
| var xmlreader = require('./xmlreader'); | ||
| var rootobject = {}; | ||
| var object = rootobject; | ||
| var someXml = '<response id="1" shop="aldi">' | ||
| + 'This is some other content' | ||
| + '<who name="james">James May</who>' | ||
| + '<who name="sam">' | ||
| + 'Sam Decrock' | ||
| + '<location>Belgium</location>' | ||
| + '</who>' | ||
| + '<who name="jack">Jack Johnsen</who>' | ||
| + '<games age="6">' | ||
| + '<game>Some great game</game>' | ||
| + '<game>Some other great game</game>' | ||
| + '</games>' | ||
| + '<notes>These are some notes</notes>' | ||
| + '</response>' | ||
| var rootobjectAttr = {}; | ||
| var objectAttr = rootobjectAttr; | ||
| xmlreader.read(someXml, function (err, res){ | ||
| // use .text() to get the content of a node: | ||
| console.log( res.response.text() ); | ||
| parser.onerror = function (err) { | ||
| // an error happened. | ||
| return console.log(err); | ||
| }; | ||
| parser.ontext = function (text) { | ||
| // got some text. t is the string of text. | ||
| console.log("text: " + text) | ||
| // use .attributes() to get the attributes of a node: | ||
| console.log( res.response.attributes().shop ); | ||
| object = text; | ||
| }; | ||
| parser.onopentag = function (node) { | ||
| // opened a tag. node has "name" and "attributes" | ||
| console.log("node:"); | ||
| console.log(node); | ||
| console.log(""); | ||
| object[node.name] = {}; | ||
| object = object[node.name]; | ||
| // using the getLength() and the at() function, you can loop through nodes with the same name: | ||
| for(var i = 0; i < res.response.who.getLength(); i++){ | ||
| console.log( res.response.who.at(i).text() ); | ||
| } | ||
| objectAttr[node.name] = {}; | ||
| objectAttr = objectAttr[node.name]; | ||
| }; | ||
| parser.onattribute = function (attr) { | ||
| // an attribute. attr has "name" and "value" | ||
| console.log("attr:"); | ||
| console.log(attr); | ||
| console.log( res.response.who.at(1).text() ) ; | ||
| console.log( res.response.who.at(1).location.text() ); | ||
| objectAttr[attr.name] = attr.value; | ||
| }; | ||
| parser.onend = function () { | ||
| // parser stream is done, and ready to have more stuff written to it. | ||
| console.log("==========================="); | ||
| // you can also get regular nodes like you get arrays: | ||
| console.log( res.response.notes.at(0).text() ); | ||
| }); | ||
| console.log(rootobject); | ||
| console.log(rootobjectAttr); | ||
| }; | ||
| parser.write('<xml>' | ||
| + '<who name="world">world</who>' | ||
| + '</xml>').close(); |
Sorry, the diff of this file is not supported yet
6522
229.23%5
25%113
189.74%67
1575%