From caf8ef7dd7b9f8367cf9dbf7d77c4d456b7e28b0 Mon Sep 17 00:00:00 2001 From: Sanchit Kapoor Date: Sat, 13 Feb 2016 20:55:09 +0530 Subject: [PATCH 1/2] Implemented loadXML() functionality #40 --- src/app.js | 1 + src/io/files.js | 36 ++++++++++--- src/io/p5.XML.js | 136 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+), 7 deletions(-) create mode 100644 src/io/p5.XML.js diff --git a/src/app.js b/src/app.js index cc7e55f95a..e755cc597e 100644 --- a/src/app.js +++ b/src/app.js @@ -12,6 +12,7 @@ require('./image/p5.Image'); require('./math/p5.Vector'); require('./io/p5.TableRow'); require('./io/p5.Table'); +require('./io/p5.XML'); require('./color/creating_reading'); require('./color/setting'); diff --git a/src/io/files.js b/src/io/files.js index af19b4bee2..f88264b57d 100644 --- a/src/io/files.js +++ b/src/io/files.js @@ -654,22 +654,44 @@ function makeObject(row, headers) { return ret; } +/*global parseXML */ +p5.prototype.parseXML = function (two) { + var one = new p5.XML(), node = new p5.XML(),i; + if(two.children.length){ + for( i = 0; i < two.children.length; i++ ) { + node = parseXML(two.children[i]); + one.addChild(node); + } + one.setName(two.nodeName); + one.setCont(two.textContent); + one.setAttributes(two); + one.setParent(); + return one; + } + else { + one.setName(two.nodeName); + one.setCont(two.textContent); + one.setAttributes(two); + return one; + } +}; + /** * Reads the contents of a file and creates an XML object with its values. * If the name of the file is used as the parameter, as in the above example, * the file must be located in the sketch directory/folder. - *

+ * * Alternatively, the file maybe be loaded from anywhere on the local * computer using an absolute path (something that starts with / on Unix and * Linux, or a drive letter on Windows), or the filename parameter can be a * URL for a file found on a network. - *

+ * * This method is asynchronous, meaning it may not finish before the next * line in your sketch is executed. Calling loadXML() inside preload() * guarantees to complete the operation before setup() and draw() are called. - *

- * Outside of preload(), you may supply a callback function to handle the - * object: + * + *

Outside of preload(), you may supply a callback function to handle the + * object:

* * @method loadXML * @param {String} filename name of the file or URL to load @@ -684,7 +706,6 @@ function makeObject(row, headers) { p5.prototype.loadXML = function (path, callback, errorCallback) { var ret = document.implementation.createDocument(null, null); var decrementPreload = p5._getDecrementPreload.apply(this, arguments); - reqwest({ url: path, type: 'xml', @@ -701,7 +722,8 @@ p5.prototype.loadXML = function (path, callback, errorCallback) { }) .then(function (resp) { var x = resp.documentElement; - ret.appendChild(x); + ret = parseXML(x); + console.log(ret); if (typeof callback !== 'undefined') { callback(ret); } diff --git a/src/io/p5.XML.js b/src/io/p5.XML.js new file mode 100644 index 0000000000..2c67f576af --- /dev/null +++ b/src/io/p5.XML.js @@ -0,0 +1,136 @@ + +'use strict'; + +var p5 = require('../core/core'); + + +p5.XML = function () { + this.name = null; //done + this.attributes = {}; //done + this.children = []; + this.parent = null; + this.content = []; //done +}; + +p5.XML.prototype.setName = function(name) { + this.name = name; +}; + +p5.XML.prototype.setParent = function() { + var i; + for( i = 0; i < this.children.length; i++ ){ + this.children[i].parent = this; + } +}; + +p5.XML.prototype.addChild = function(node) { + this.children.push(node); +}; + +p5.XML.prototype.setCont = function(content) { + var str; + str = content; + str = str.replace(/\s\s+/g, ','); + str = str.split(','); + this.content = str; +}; + +p5.XML.prototype.setAttributes = function(node) { + var i, att = {}; + for( i = 0; i < node.attributes.length; i++) { + att[node.attributes[i].nodeName] = node.attributes[i].nodeValue; + } + this.attributes = att; +}; + +p5.XML.prototype.getParent = function() { + return this.parent; +}; + +p5.XML.prototype.getName = function() { + return this.name; +}; + +p5.XML.prototype.hasChildren = function() { + if(this.children) { + return true; + } + else { + return false; + } +}; + +p5.XML.prototype.listChildren = function() { + var i, arr = []; + for( i = 0; i < this.children.length; i++ ) { + arr.push(this.children[i].name); + } + return arr; +}; + +p5.XML.prototype.getChildren = function(param) { + if (param) { + var i, arr = []; + for( i = 0; i < this.children.length; i++ ) { + if (this.children[i].name === param) { + arr.push(this.children[i]); + } + } + return arr; + } + else { + return this.children; + } +}; + +p5.XML.prototype.getChild = function(param) { + if(typeof param === 'string') { + return this.children[0]; + } + else { + var i; + for( i = 0; i < this.children.length; i++ ) { + if(i === param) { + return this.children[i]; + } + } + } +}; + +p5.XML.prototype.removeChild = function(node) { + var i; + for( i = 0 ; i < this.children.length; i++ ) { + if( this.children[i] === node ) { + delete this.children[i]; + } + } +}; + +p5.XML.prototype.getAttributeCount = function() { + return Object.keys(this.attributes).length; +}; + +p5.XML.prototype.listAttributes = function() { + return Object.keys(this.attributes); +}; + +p5.XML.prototype.hasAttribute = function(name) { + var i; + var names = Object.keys(this.attributes); + for( i = 0 ; i < names.length ; i++ ) { + if(name === names[i]) { + return true; + } + } + return false; +}; + +p5.XML.prototype.getContent = function() { + return this.content; +}; + +p5.XML.prototype.setContent = function( content ) { + if(!this.children.length) { + this.content = content; + } +}; From f8e7ac0486c9c0a9756ea531f2be72a4feab2a93 Mon Sep 17 00:00:00 2001 From: Sanchit Kapoor Date: Sat, 13 Feb 2016 22:54:23 +0530 Subject: [PATCH 2/2] Add method descriptions --- src/io/p5.XML.js | 124 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/src/io/p5.XML.js b/src/io/p5.XML.js index 2c67f576af..2acf294c3d 100644 --- a/src/io/p5.XML.js +++ b/src/io/p5.XML.js @@ -1,3 +1,8 @@ +/** + * @module IO + * @submodule XML + * @requires core + */ 'use strict'; @@ -12,10 +17,24 @@ p5.XML = function () { this.content = []; //done }; +/** + * Method called when the name of an XML Node needs to be changed + * + * @method setName + * @param {String} the new name of the node + */ p5.XML.prototype.setName = function(name) { this.name = name; }; +/** + * Method used to set the parent of a node. Used mainly during the + * parsing of XML when loadXML() is called. The XML node (the p5.XML + * Object) is passed and the children of that node are set to have + * their parent as the node which was passed + * + * @method setParent + */ p5.XML.prototype.setParent = function() { var i; for( i = 0; i < this.children.length; i++ ){ @@ -23,10 +42,28 @@ p5.XML.prototype.setParent = function() { } }; +/** + * Method used to add a new child to an XML node. The node on being + * passed gets pushed to the children array of the parent node. + * + * @method addChild + * @param {Object} a p5.XML Object which will be the child to be added + */ p5.XML.prototype.addChild = function(node) { this.children.push(node); }; +/** + * This method is called while the parsing of XML (when loadXML() is + * called). The difference between this method and the setContent() + * method defined later is that this one is used to set the content + * when the node in question has more nodes under it and so on and + * not directly text content. While in the other one is used when + * the node in question directly has text inside it. + * + * @method setCont + * @param {String} the content (might be large if more nodes inside) + */ p5.XML.prototype.setCont = function(content) { var str; str = content; @@ -35,6 +72,14 @@ p5.XML.prototype.setCont = function(content) { this.content = str; }; +/** + * This method is called while the parsing of XML (when loadXML() is + * called). The XML node is passed and its attributes are stored in the + * p5.XML's attribute Object. + * + * @method setAttributes + * @param XML Node + */ p5.XML.prototype.setAttributes = function(node) { var i, att = {}; for( i = 0; i < node.attributes.length; i++) { @@ -43,14 +88,33 @@ p5.XML.prototype.setAttributes = function(node) { this.attributes = att; }; +/** + * getParent() when called returns the parent (a p5.XML Object) + * of the node. + * + * @method getParent + * @return {Object} a p5.XML Object which is the parent + */ p5.XML.prototype.getParent = function() { return this.parent; }; +/** + * getName() when called returns the name of the node. + * + * @method getName + * @return {String} the name of the node + */ p5.XML.prototype.getName = function() { return this.name; }; +/** + * hasChildren() to check whether the node has any children. + * + * @method hasChildren + * @return {boolean} true if yes otherwise false + */ p5.XML.prototype.hasChildren = function() { if(this.children) { return true; @@ -60,6 +124,13 @@ p5.XML.prototype.hasChildren = function() { } }; +/** + * hasChildren() when called returns all the children of the node + * in an array of String + * + * @method listChildren + * @return {Array} an array of Strings storing all the names of children + */ p5.XML.prototype.listChildren = function() { var i, arr = []; for( i = 0; i < this.children.length; i++ ) { @@ -68,6 +139,14 @@ p5.XML.prototype.listChildren = function() { return arr; }; +/** + * getChildren() when called returns all the children (p5.XML Objects) + * of the node + * + * @method getChildren + * @param {String} if passed will only return those children matching param. + * @return {Array} an array containing all the children (p5.XML Objects) + */ p5.XML.prototype.getChildren = function(param) { if (param) { var i, arr = []; @@ -83,6 +162,14 @@ p5.XML.prototype.getChildren = function(param) { } }; +/** + * getChild() when called returns the child element with the specified index + * value or name (the first node with that name) + * + * @method getChild + * @param {String|number} + * @return {Object} a p5.XML Object + */ p5.XML.prototype.getChild = function(param) { if(typeof param === 'string') { return this.children[0]; @@ -97,6 +184,12 @@ p5.XML.prototype.getChild = function(param) { } }; +/** + * removeChild() removes the child (p5.XML Object) which is passed + * + * @method getParent + * @param {Object} the child (p5.XML Object) to be removed + */ p5.XML.prototype.removeChild = function(node) { var i; for( i = 0 ; i < this.children.length; i++ ) { @@ -106,14 +199,33 @@ p5.XML.prototype.removeChild = function(node) { } }; +/** + * getAttributeCount() returns the number of attributes an XML node has + * + * @method getAttributeCount + * @return {Number} + */ p5.XML.prototype.getAttributeCount = function() { return Object.keys(this.attributes).length; }; +/** + * listAttributes() returns a list of all the attributes of the XML node. + * + * @method listAttributes + * @return {Array} an array of strings containing the names of attributes + */ p5.XML.prototype.listAttributes = function() { return Object.keys(this.attributes); }; +/** + * hasAttribute() checks whether the node in question has the passed attribute. + * + * @method hasAttribute + * @param {String} the attribute to be checked + * @return {boolean} true if attribute found else false + */ p5.XML.prototype.hasAttribute = function(name) { var i; var names = Object.keys(this.attributes); @@ -125,10 +237,22 @@ p5.XML.prototype.hasAttribute = function(name) { return false; }; +/** + * getContent() returns the content inside an XML node. + * + * @method getContent + * @return {String} + */ p5.XML.prototype.getContent = function() { return this.content; }; +/** + * setContent() sets the content of the XML node. + * + * @method setContent + * @param {String} the new content + */ p5.XML.prototype.setContent = function( content ) { if(!this.children.length) { this.content = content;