XML to javascript array with jQuery - javascript

I am new to XML and AJAX and am only a newcomer to Javascript and jQuery. Among other job duties I design our website. A deadline is very near, and the only way I can think of to do this project well is with AJAX. I have a document full of XML objects such as this one repeating:
<item>
<subject></subject>
<date></date>
<thumb></thumb>
</item>
I want to create an array of all elements and their child elements. I've been reading jQuery tutorials on AJAX for hours and don't even know where to start because they all assume a certain level of javascript proficiency. If someone could show me the easiest way to loop through all elements and put their children into an array, I'd appreciate it tons.

Using jQuery, $.ajax() your XML file, and on success pass retrieved data with each, like:
var tmpSubject, tmpDate, tmpThumb;
$.ajax({
url: '/your_file.xml',
type: 'GET',
dataType: 'xml',
success: function(returnedXMLResponse){
$('item', returnedXMLResponse).each(function(){
tmpSubject = $('subject', this).text();
tmpDate = $('date', this).text();
tmpThumb = $('thumb', this).text();
//Here you can do anything you want with those temporary
//variables, e.g. put them in some place in your html document
//or store them in an associative array
})
}
});

I wrote this.. pretty simple way to take a welformed XML response/string and parse it with jquery and then convert to array.
var response = '<?xml version="1.0" encoding="UTF-8"?><root><node1>something</node1></root>'
var xmlDoc = $.parseXML( response );
var myArray = getXMLToArray(xmlDoc);
alert(myArray['root']['node1']);
//Pop up window displaying the text "something"
function getXMLToArray(xmlDoc){
var thisArray = new Array();
//Check XML doc
if($(xmlDoc).children().length > 0){
//Foreach Node found
$(xmlDoc).children().each(function(){
if($(xmlDoc).find(this.nodeName).children().length > 0){
//If it has children recursively get the inner array
var NextNode = $(xmlDoc).find(this.nodeName);
thisArray[this.nodeName] = getXMLToArray(NextNode);
} else {
//If not then store the next value to the current array
thisArray[this.nodeName] = $(xmlDoc).find(this.nodeName).text();
}
});
}
return thisArray;
}
Hope this helps!!

If you are using jQuery then parseXML will suck an entire xml doc into a usable data structure.

I added to your script Troublesum
function getXMLToArray(xmlDoc){
var thisArray = new Array();
//Check XML doc
if($(xmlDoc).children().length > 0){
//Foreach Node found
$(xmlDoc).children().each(function(){
if($(xmlDoc).find(this.nodeName).children().length > 0){
//If it has children recursively get the inner array
var NextNode = $(xmlDoc).find(this.nodeName);
thisArray[this.nodeName] = getXMLToArray(NextNode);
} else {
//If not then store the next value to the current array
thisArray[this.nodeName] = [];
$(xmlDoc).children(this.nodeName).each(function(){
thisArray[this.nodeName].push($(this).text());
});
}
});
}
return thisArray;
}
It now also supports many children with same name in XML. f.e
XML being
<countries>
<NL>
<borders>
<country>Germany</country>
<country>Belgium</country>
countries.NL.borders[1] will give Germany.

Related

How to retrieve a specific object from a JSON value stored in sessionStorage?

I have this stored in the session:
What I'm looking to do is assign each object in the JSON as a variable so I can add them to the DOM appropriately.
This works but prints everything out:
if (sessionStorage.getItem('wc_fragments_aaf6a2e5b971cb51d59e8f3eae9b34c9') != null) {
$(sessionStorage.getItem('wc_fragments_aaf6a2e5b971cb51d59e8f3eae9b34c9')).appendTo('.div');
}
What I'd like is something like this, but it doesn't work:
var div1 = $(JSON.parse(sessionStorage.getItem('wc_fragments_aaf6a2e5b971cb51d59e8f3eae9b34c9', 'a.cart-contents')));
var div2 = $(JSON.parse(sessionStorage.getItem('wc_fragments_aaf6a2e5b971cb51d59e8f3eae9b34c9', 'a.footer-cart-contents')));
var div3 = $(JSON.parse(sessionStorage.getItem('wc_fragments_aaf6a2e5b971cb51d59e8f3eae9b34c9', 'div.widget_shopping_cart_content')));
Any help would be greatly appreciated. Thank you!
Getting the same value from the storage several times is not a good idea. In addition, you need better names for your variables.
var json = sessionStorage.getItem('wc_fragments_aaf6a2e5b971cb51d59e8f3eae9b34c9');
if (json) {
var data = JSON.parse(json);
if (data) {
var cart_link = $(data['a.cart-contents']),
footer_link = $(data['a.footer-cart-contents']),
widget_div = $(data['div.widget_shopping_cart_content']);
}
}
So it appears you have set selectors as keys of the object so you could iterate those keys to get each selector.
The propose of those selector keys is not 100% clear. I am assuming that those selectors are the elements you want to insert the html strings into and that $() means you are using jQuery
if (sessionStorage.getItem('wc_fragments_aaf6a2e5b971cb51d59e8f3eae9b34c9') != null) {
var data = JSON.parse(sessionStorage.getItem('wc_fragments_aaf6a2e5b971cb51d59e8f3eae9b34c9');
$.each(data, function(selector, htmlString){
$(selector).append(htmlString)
});
}

Converting AJAX'd-in XML to HTML

I have a web page that allows the user to select a category from a dropdown list. The category relates to a table that is derived from an XML file that is AJAX'd in. I intend to use some JS code to read the contents of the XML file and create a table based on the values therein. (In other words, the XML files could create tables with completely different columns, which is why I don't want to hard code anything, but would rather have it built programatically.) I also don't want to use XSLT or any other methods that would create a second set of files; the XML files used are to be considered the "sources of truth".
I can get an XML file to load, but I'm having difficulty navigating the structure in order to read column names from the first child element.
<xml>
<item>
<number>Number</number>
<image>Image</image>
</item>
<item>
<number>123</number>
<image>123.jpg</image>
</item>
</xml>
I'd like to be able to read the first set of <item> elements and use their text values to generate the <th> elements in the table. And then fill in the table with the rest of the XML content.
I've tried items[0].childNodes[0], but it picks up the line breaks (which I don't want to remove from the XML source files).
I've also tried items[0].children[0], but I get "Unable to get property '0' of undefined or null reference".
Here is my code thus far:
const vPathToJSON = "../JSON/";
const vPathToXML = "../XML/";
var vCategoriesJSON = "categoriesJSON.txt";
// Perform functions after DOM is readyState
$("document").ready(
function() {
getFromFile(vPathToJSON, vCategoriesJSON, "JSON")
.then(fillCategoriesDropdown)
.then(getFromFile(vPathToXML, "acMitigation.xml", "XML"));
}
);
// Use jQuery AJAX "GET" function to import from file and parse as
requested
function getFromFile(pFilePath, pFileName, pParseType) {
var vCompletePath = pFilePath + pFileName;
switch(pParseType) {
case "JSON":
return $.get(vCompletePath)
.then(function(returnedText) {
return JSON.parse(returnedText);
});
case "XML":
$.ajax({
type: "GET",
url: vCompletePath,
dataType: "xml",
success: function(xml) {
console.log("Success!");
fillMainTable(xml);
},
error: function() {
console.log("Unsuccessful!");
}
});
break;
}
}
// Fill Category dropdown dynamically based on returned JSON file values
function fillCategoriesDropdown(pReturnedJSON) {
for (i = 0; i < pReturnedJSON.length; i++) {
var vNewOption = document.createElement("OPTION");
vNewOption.text = pReturnedJSON[i].category;
document.getElementById("id_CategorySelect").appendChild(vNewOption);
aListOfCategories[i] = pReturnedJSON[i];
}
}
function fillMainTable(pXML) {
var items = pXML.getElementsByTagName("item");
// ???
}
Any and all help is appreciated!
I'm not sure if this is the best strategy, but it's working at least.
FYI, I changed the name of the function to more accurately describe what it does.
The main problem I was facing was that it was picking up the empty text nodes, which made navigating the element tree confusing.
function getColumnNames(pXML) {
var entriesElement = pXML.childNodes[0].childNodes[1].nodeName; //finds <item>
var items = pXML.getElementsByTagName(entriesElement); //array of <item> elements
var columns = []; //column elements and names
var j = 0;
// childNodes starts at 1 and goes up by 2 to skip empty text nodes in <item>
for (i = 1; i < items[0].childNodes.length; i += 2) {
var elementName = items[0].childNodes[i].nodeName;
var elementValue = items[0].childNodes[i].textContent;
columns[j] = {
"elementName":elementName,
"elementValue":elementValue};
console.log(columns[j]);
j++;
}
}

When stringifying an object, JSON turns element nodes into Objects?

So I'm working on a little personal project and I came upon a problem.
I need each day object to hold various dom element objects. These object instances are stored in an array and then that array needs to be stored into localStorage to load later.
The problem is when I do JSON.stringify and then JSON.parse it converts the HTML nodes into objects. So when I try to append element it tells me that the first parameter is not a node.
function save() {
localStorage.days = JSON.stringify(global.days);
localStorage.numberOfDays = global.numberOfDays;
localStorage.totalCount = global.totalCount;
}
function load() {
var parsedDays = JSON.parse(localStorage.days);
parsedDays.forEach(function(day){
document.getElementById("mainPage").appendChild(day.textObject);
});
anyone know how I can put an array of objects which hold elements into localStorage while keeping their node type????
If you will try to stringify dom nodes then it will return "{}".So its not possible to store node as it is inside localstorage.
What you can do is store information regarding nodes inside localstorage and recreate your node from that information and add it in your dom.
You'd probably need to have a property eg 'type' that defines the element type
var elem
parsedDays.forEach(function(day){
elem = document.getElementById("mainPage").createElement(day.type);
elem.attributes = day.attributes;
elem.innerHTML = day.textObject;
});
Or something like that, not too sure without seeing your day object
Use JSON.stringify and JSON.parse
Example Code:
Element.prototype.toJSON = function (){
return {nodeType:this.nodeType, outerHTML:this.outerHTML};
};
function replacer(k,v){
if(v.nodeType===1 && v.outerHTML){
var ele = document.createElement('html');
ele.innerHTML = v.outerHTML;
return ele.removeChild(ele.firstChild);
}
return v;
}
//test
var jstr = JSON.stringify({ele:document.body});
var json = JSON.parse(jstr,replacer);
console.log(jstr);
console.log(json);

Parse 2-dimensional array retrieved as string from database

I am building an array of data that is being retrieved from the cells of a table. The resulting array looks something like this:
[["","","",""],["","9/2/14","","9/17/14"],["","","89ol",""],["","687k","","9-0["p/"],["","245g","245g","356h"],["","","",""],["","","4j6","467j"],["","","9/9/14",""]]
I'm saving the data to a MySQL database as a string in one field. I now need to retrieve that data and iterate through it to repopulate the table.
I'm getting the data to an $.ajax function as a string in the above format.
How can I get the individual cell data to populate the cells properly?
UPDATE:
Here's the php code I'm using to retrieve the data:
$queryGetUserTaskNotes = "SELECT userProgressNotes FROM userProgress WHERE userProgressUserID = $userID AND userProgressSiteID = $siteID and userProgressNotesTable = '" . $taskTableID . "'";
$resultGetUserTaskNotes = #mysqli_query($dbc,$queryGetUserTaskNotes);
if ($resultGetUserTaskNotes) {
$taskNotes = mysqli_fetch_assoc($resultGetUserTaskNotes);
echo $taskNotes['userProgressNotes'];
}
Here's how I'm getting the data from the php script
function GetTaskNotes(siteID,tableID) {
$.ajax({
url: 'script.php',
data: {getTaskNotes:'true', userID:userID, siteID:siteID, tableID:tableID},
success: function(data) {
console.log('GetTaskNotes data: ' + data);
}
});
}
As for what I've tried so far, I've been working with how to parse the string on the js side in the success function. JSON.parse(data) didn't work and frankly, I'm not sure what else to try.
Thanks!
Unless you have very special needs in terms of performance/logic, I would say it would be better to use a hash of name/value pairs (a.k.a an object) where the names in the hash correspond to actual fields in the database. That being said, lets say for the sake of argument that the arrays are populated by .push() calls, in which case a simple nested for loop should work:
'use strict';
var array = JSON.parse(string);
var cell, row, i, j;
var table = document.createElement('table');
for (i=0; i < array.length; ++i) {
row = document.createElement('tr');
for (j=0; j < array[i].length; ++j) {
cell = document.createElement('td');
cell.innerHTML = array[i][j];
row.appendChild(cell);
}
table.appendChild(row);
}
document.appendChild(table);
Where string is the string you get back from the DB when its time to repopulate.
I think the steps here for you are going to be:
In PHP, provide a URL that JS can do a GET against that will return the data. The way that is structured and looks will depend somewhat on what framework (if any) that you're using. Be sure to return that data as JSON using a built in PHP JSON encode method.
In JS, do a GET like so:
$.ajax({
url: 'your url here',
type: 'GET',
success: function(data) { console.log(data); }
});
In your success function, I assume you'll handle iterating over your object and inserting it into the DOM. I would look at jQuery's $.each() method for that. When it comes to "populating the cells properly", it'd be helpful to see your HTML and JS in a jsFiddle or something.
Good luck!
References:
http://api.jquery.com/jQuery.ajax/
http://api.jquery.com/jquery.each/

How to read xml data and seperate it by tag

I am trying to read xml data and separate it by tag names so that I can save the values in variables for future use. But I am unable to read and filter the xml values. I need to read each value from the page given and seperate the tag values.
Following is my code-
I need to filter the data by CustomerID and find the particular email of the customer.
Can anyone help me please.
$.get("/read_xml.asp", function(XMLresponse) {
var xmldata=XMLresponse;
alert("Data Loaded: " + xmldata);
// Customers
alert(str.length);
var str =xmldata;
str = str.split('<CustomerID>');
str[1] = str[1].split('</CustomerID>');
alert(str[1]);
});
XML can be accessed like this (if it is valid):
var customerID = xmldata.getElementByTagName('CustomerID')[0].nodeValue;
like if it is a list:
for(var i = 0;i<xmldata.getElementByTagName('customer').length;i++){
var customer = xmldata.getElementByTagName('customer')[i];
var customerID = customer.getElementByTagName('CustomerID')[0].nodeValue;
}
As said in comments, one must see your XML that you receive from that ajax call.
However, to traverse your document or to find elements with jquery is obvious.
$(xml).find('ParentElement').each(function(){
var id = $(this).attr('CustomerID');
var title = $(this).find('CustomerTitle').text();
var other = $(this).find('CustomerOther').text();
});
You can use $.parseXML and then query the document like you would query the DOM using selectors.
var xml = "<rss version='2.0'><channel><title>RSS Title</title></channel></rss>",
xmlDoc = $.parseXML( xml ), //create a document from the XML string
$xml = $( xmlDoc ), //wrap the document in a jQuery object
$title = $xml.find( "title" ); //find every title tags
The example comes from the source I linked, but I added comments.

Categories

Resources