I am new to jquery. I am trying to parse xml string using jquery. I have found one sample:
$(function () {
$.get('data.xml', function (d) {
var data = "";
var startTag = "<table border='1' id='mainTable'><tbody><tr><td style=\"width: 120px\">Name</td><td style=\"width: 120px\">Link</td></tr>";
var endTag = "</tbody></table>";
$(d).find('url').each(function () {
var $url = $(this);
var link = $url.find('link').text();
var name = $url.find('name').text();
data += '<tr><td>' + name + '</td>';
data += '<td>' + link + '</td></tr>';
});
$("#content").html(startTag + data + endTag);
});
});
In this case, I am able to parse and fetch the values from xml file, but now what I am looking for is instead of reading file from a URL, I want to read the xml from string. Say, instead of data.xml I want to parse string which consists of well formed xml.
Does anyone have any idea about this ?
Thanks in advance
Edit :
I tried a sample code on following xml;
<?xml version="1.0" encoding="utf-8" ?>
<Urls>
<url>
<name>google</name>
<link>www.google.com</link>
</url>
<url>
<name>aspdotnetcodebook</name>
<link>http://aspdotnetcodebook.blogspot.com</link>
</url>
</Urls>
When I try this on xml file, everything works fine. But when I switched to string, it returns nothing for link attribute. I am calling it as;
$(function() {
var data = $('<?xml version="1.0" encoding="utf-8" ?><Urls><url><name>google</name><link>www.google.com</link></url><url><name>aspdotnetcodebook</name><link>http://aspdotnetcodebook.blogspot.com</link></url></Urls>');
alert(data);
doWhateverItIsYourDoing(data);
});
I am unable to diagnose why this is happening.
Just pass the string directly?
function doWhateverItIsYoureDoing(xml) {
var data = "";
var startTag = "<table border='1' id='mainTable'><tbody><tr><td style=\"width: 120px\">Name</td><td style=\"width: 120px\">Link</td></tr>";
var endTag = "</tbody></table>";
$(xml).find('url').each(function() {
var $url = $(this);
var link = $url.find('link').text();
var name = $url.find('name').text();
data += '<tr><td>' + name + '</td>';
data += '<td>' + link + '</td></tr>';
});
$("#content").html(startTag + data + endTag);
}
your .get could be rewritten as:
$.get('data.xml',doWhateverItIsYoureDoing );
and if you have xml in a string already, then
var data = "<?xml version=\"1......";
doWhateverItIsYoureDoing(data);
Just put that well-formed XML string into a jQuery object:
var xml = "<?xml version=\"1.0\"?><Dialog><Adam Emotion=\"strong\">I love you!</Adam><Eva Emotion=\"low\">I love you, too!</Eva></Dialog>";
access with
alert($(xml).find('Adam').text());
or
alert($(xml).find('Adam').attr('Emotion'));
put the the XML string into javascript variable
var xmlString = $(‘<?xml version=”1.0″?><Customers><Customer Name=”Allan Border” Age=”26″ ContactNumber=”004416165245″ Address=”Unit # 24 East London” City=”London” Country=”England”></Customer><Customer Name=”Jennifer” Age=”28″ ContactNumber=”004416165248″ Address=”Unit # 28 West London” City=”London” Country=”England”></Customer></Customers>’);
Now you can parse the XML as iterate through each of the customer node…
$(xmlString).find("Customer").each(function () {
var customerName = $(this).attr("Name");
var age = $(this).attr("Age");
var contactNumber = $(this).attr("ContactNumber");
var address = $(this).attr("Address");
var city = $(this).attr("City");
var country = $(this).attr("Country");
});
Note that to properly parse any type of XML file, you want to use the parseXML() function as in:
var xml_jquery_object = jQuery.parseXML(xml);
When you do as presented in the other answers:
var html_jquery_object = jQuery(xml);
you ask jQuery to parse HTML and not XML. The big difference is that HTML removes some tags (body, html, head...) and expects certain tags to be empty (br, hr, ...). So it is likely to break the parsing of your XML file if it somehow includes such tags.
xml can be a direct string as well, of course. The AJAX .get() function returns a string to your function anyway. (The better .ajax() function can return an XML object directly.) So you may define any XML code in that variable as in:
xml = "<?xml version='1.0'?><test>...</test>";
Related
I got a question regarding passing the value of the select option to my XML parser. First look at my code:
HTML
<table id="ProfileList">
<tr>
<td>session</td>
<td>timestamp</td>
</tr>
</table>
<select>
<option value="none">--select user--</option>
<option value="user20">user20</option>
<option value="user30">user30</option>
<option value="user40">user40</option>
<option value="user50">user50</option>
</select>
As you can see I have a select box with 5 options were only the last four are important.
Javascript
$('select').change(function() {
var user = $(this).val();
alert($(this).val());
//Sample XML
var user20 = "<?xml version='1.0' ?><results><row><session>21</session><time>2014-02-28 21:12:12</time></row><row><session>176763</session><time>2014-03-01 14:04:35</time></row></results>";
var user30 = "<?xml version='1.0' ?><results><row><session>26</session><time>2014-02-28 21:12:12</time></row><row><session>176763</session><time>2014-03-01 14:04:35</time></row></results>";
//Parse the givn XML
var xmlDoc = $.parseXML( user );
var $xml = $(xmlDoc);
var $row = $xml.find("row");
$row.each(function(){
var session = $(this).find('session').text(),
time = $(this).find('time').text();
$("#ProfileList" ).append('<tr><td>' +session+ '</td>' + '<td>' +time+ '</td></tr>');
});
});
What I want is that the value of my select option is used as input for my XML parser. If I run this code, then I will get an error that the XML is invalid.
To clarify: If I set a fixed value then it works:
var xmlDoc = $.parseXML( user20 );
But if I want to set it variable it does not work:
var xmlDoc = $.parseXML( user );
Can anyone tell me why this is and perhaps how I could solve this?
DEMO CAN BE FOUND HERE
I would use an object containing the XML samples and access each XML by its property name of the object, see http://jsfiddle.net/3po6xgmt/ which does
$('select').change(function() {
var user = $(this).val();
alert($(this).val());
//XML samples
var samples = {
user20 : "<?xml version='1.0' ?><results><row><session>21</session><time>2014-02-28 21:12:12</time></row><row><session>176763</session><time>2014-03-01 14:04:35</time></row></results>",
user30 : "<?xml version='1.0' ?><results><row><session>26</session><time>2014-02-28 21:12:12</time></row><row><session>176763</session><time>2014-03-01 14:04:35</time></row></results>"
};
//Parse the given XML
var xmlDoc = $.parseXML( samples[user] );
var $xml = $(xmlDoc);
var $row = $xml.find("row");
$row.each(function(){
var session = $(this).find('session').text(),
time = $(this).find('time').text();
$("#ProfileList" ).append('<tr><td>' +session+ '</td>' + '<td>' +time+ '</td></tr>');
});
});
I started working with APIs/Ajax/JSON recently and began a small project to test my knowledge.
I made a simply website where you type a word into a form and it brings back Flickr photos associated with the word.
It works pretty well, but it always includes a simple "undefined" before the first photo which messes with the display of the first row of pictures.
An example can be seen here, simply search for a photo tag and you'll see what I'm talking about:
http://codepen.io/anon/pen/jPExNm
Here is the related jQuery:
$('form').submit(function (evt) {
evt.preventDefault();
// the AJAX part
var flickerAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
var query = $('#photoQuery').val();
var flickrOptions = {
tags: query,
format: "json"
};
function displayPhotos(data) {
var photoHTML;
$.each(data.items,function(i,photo) {
photoHTML += '<div class="photo">';
photoHTML += '<a href="' + photo.link + '" class="image">';
photoHTML += '<img src="' + photo.media.m + '"></a></div>';
}); // end each
$('#photoGallery').html(photoHTML);
}
$.getJSON(flickerAPI, flickrOptions, displayPhotos);
}); // end submit
I haven't found any errors related to this in the Javascript console and couldn't find anything like this while Googling, so I'm turning to StackOverflow. Thank you for any and all help.
Because
var photoHTML;
is the same thing as
var photoHTML = undefined;
Basic example of what you are doing
var str;
str = str + "123"; // undefined + "123" = "undefined123";
You need to set it to an empty string
var photoHTML = "";
i am receiving xml as a web response.
<s:Envelope xmlns:s="http://schemas.example.org/soap/envelope/">
<s:Header/>
<s:Body>
<ProductIdResponse xmlns="http://example.org/">
<Product>123</Product>
<ProductIdResponse>
</s:Body>
</s:Envelope>
I am looking to extract value from xml using pure javascript and store it in variable. there are many example in stackoverflow but all are using DOM elements and jquery.
any help would be appreciated.
have a look here: XML Parser
you load the xml into an xml document, and then access the elements the same way you would on your page's document:
//initialize your xml for testing purposes
txt='<s:Envelope xmlns:s="http://schemas.example.org/soap/envelope/">';
txt=txt+'<s:Header/>';
txt=txt+'<s:Body>';
txt=txt+'<ProductIdResponse xmlns="http://example.org/">';
txt=txt+' <Product>123</Product>';
txt=txt+'<ProductIdResponse>';
txt=txt+'</s:Body>';
txt=txt+'</s:Envelope>';
if (window.DOMParser) {
parser = new DOMParser();
xmlDoc = parser.parseFromString(txt, "text/xml");
} else // Internet Explorer
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.loadXML(txt);
}
var myProduct = xmlDoc.getElementsByTagName("Product")[0].innerHTML;
alert(myProduct);
If you dont want to parse the xml into DOM, you can alternatively retrieve the data using RegEx matching
check Here for a good RegEx tester where you can practice regex.
//initialize your xml for testing purposes
txt = '<s:Envelope xmlns:s="http://schemas.example.org/soap/envelope/">';
txt = txt + '<s:Header/>';
txt = txt + '<s:Body>';
txt = txt + '<ProductIdResponse xmlns="http://example.org/">';
txt = txt + ' <Product>123</Product>';
txt = txt + ' <Product>Product 2</Product>';
txt = txt + '<ProductIdResponse>';
txt = txt + '</s:Body>';
txt = txt + '</s:Envelope>';
var myProducts = txt.match(/<Product>(.*?)<\/Product>/g);
myProducts.forEach(function(val, id) {
myProducts[id] = myProducts[id].replace(/(<([^>]+)>)/ig, "");
});
console.log(myProducts);
alert("2nd product is: " + myProducts[1]);
As I need to bring separate data from a php file, and create an HTML piece to be injected with jQuery, I've choosen Json.
I send it from my PHP main file (between script tags) like this:
$.ajax({dataType: "json", url:'course_generator.php', data:{co_subj_co:editedCourseId}}).done(function(newCourse){
var newCourseStructure = '<div class="tableRow dynamicRow noHeight injectedRow" data-isMultisubjectValue="'+isMultisubjectValue+'" data-subjectsNum="'+subjectsNum+'" data-id="'+courseId+'" id="'+courseId+'" data-abbrev="'+newCourseAbbrev+'" data-courseTypeId="'+newCourseTypeId+'" title="'+newCourseName+'"><div class="contentColumn40"><span class="tableContentText">'+newCourseName+' ('+newCourseTypeName+')</span></div><div class="contentColumn40">'+subjectList+'</div><div class="contentColumn10"><div class="tableIconLink"><div class="editIcon" data-id="'+courseId+'" title="Editar '+newCourseName+'"></div></div></div><div class="contentColumn10"><div class="tableIconLink"><div data-id="'+courseId+'" class="discontinueIcon" title="Discontinuar '+newCourseName+'"></div></div></div></div>';}
This sends properly editedCourseId value. And what's inside course_generator.php is:
$courseId = $_POST['co_subj_co'];
$select_co = mysql_query("SELECT * FROM course_conf JOIN course_type ON co_fk_ct_id=ct_id JOIN co_rel_subj ON co_subj_co='$courseId' JOIN subject_conf ON su_id=co_subj_subj WHERE co_id='$courseId'");
$result_co = mysql_fetch_array($select_co);
$newCourseId = $result_co['co_id'];
$newCourseName = $result_co['co_name'];
$newCourseAbbrev = $result_co['co_abbrev'];
$newCourseTypeId = $result_co['co_fk_ct_id'];
$newCourseTypeName = $result_co['ct_name'];
$isMultisubjectValue = $result_co['co_multisubject'];
$newCourseValues = '{"newCourseId":'.$newCourseId.',"newCourseName":'.$newCourseName.',"newCourseAbbrev":'.$newCourseAbbrev.',"newCourseTypeId":'.$newCourseTypeId.',"newCourseTypeName":'.$newCourseTypeName.',"isMultisubjectValue":'.$isMultisubjectValue.'}';
I am afraid Im not receiving it properly by $courseId = $_POST['co_subj_co'];, and neither $newCourseValues are being received properly on my main PHP file as my newCourseStructure is not generating anything. Could you please identify the several errors I am sure I'm making? Thank you.
UPDATE:
After changing my PHP main file to:
$.ajax({type : 'POST', dataType: "json", url:'config/forms/course_conf/course_generator.php', data:{co_subj_co:editedCourseId}}).done(function(newCourse){
var courseId = newCourse.newCourseId;
var newcourseName = newCourse.newCourseName;
var isMultisubjectValue = newCourse.isMultisubjectValue;
var subjectsNum = newCourse.subjectsNum;
var newCourseAbbrev = newCourse.newCourseAbbrev;
var newCourseTypeId = newCourse.newCourseTypeId;
var newCourseTypeName = newCourse.newCourseTypeName;
var newCourseStructure = '<div class="tableRow dynamicRow noHeight injectedRow" data-isMultisubjectValue="'+isMultisubjectValue+'" data-subjectsNum="'+subjectsNum+'" data-id="'+courseId+'" id="'+courseId+'" data-abbrev="'+newCourseAbbrev+'" data-courseTypeId="'+newCourseTypeId+'" title="'+newCourseName+'"><div class="contentColumn40"><span class="tableContentText">'+newCourseName+' ('+newCourseTypeName+')</span></div><div class="contentColumn40">'+subjectList+'</div><div class="contentColumn10"><div class="tableIconLink"><div class="editIcon" data-id="'+courseId+'" title="Editar '+newCourseName+'"></div></div></div><div class="contentColumn10"><div class="tableIconLink"><div data-id="'+courseId+'" class="discontinueIcon" title="Discontinuar '+newCourseName+'"></div></div></div></div>';}
And my course_generator.php file to:
$courseId = intval($_POST['co_subj_co']);
$subjectList = "";
$data ="";
$select_co = mysql_query("SELECT * FROM course_conf JOIN course_type ON co_fk_ct_id=ct_id JOIN co_rel_subj ON co_subj_co='$courseId' JOIN subject_conf ON su_id=co_subj_subj WHERE co_id='$courseId'");
$result_co = mysql_fetch_array($select_co);
$outArr['newCourseId'] = $result_co['co_id'];
$outArr['newCourseName'] = $result_co['co_name'];
$outArr['newCourseAbbrev'] = $result_co['co_abbrev'];
$outArr['newCourseTypeId'] = $result_co['co_fk_ct_id'];
$outArr['newCourseTypeName'] = $result_co['ct_name'];
$outArr['isMultisubjectValue'] = $result_co['co_multisubject'];
$subjectsNum=mysql_num_rows(mysql_query("SELECT * FROM co_rel_subj WHERE co_subj_co = '$courseId'"));
$outArr['subjectsNum'] = $subjectsNum;
echo json_encode($outArr);
Instead of showing the HTML piece structured, this is what $newCourseStructure results:
{"newCourseId":"243","newCourseName":"a","newCourseAbbrev":"ae","newCourseTypeId":"1","newCourseTypeName":"M\u00e1ster","isMultisubjectValue":"1","subjectList":"
Edici\u00f3n y Acabado de Imagen Digital<\/div>
","subjectsNum":1}
Your JSON string is not valid JSON because you don't use quotes around the string values. Instead of manually creating JSON, create an array or object and then json_encode() it.
You don't apper to output the JSON string. Use echo or print.
Add dataType : 'json' to your ajax request so that jQuery will parse the JSON, returning the native JavaScript object. All of the variables you use in the success function are undefined. After parsing the JSON you should use
var courseId = newCourse.newCourseId; // and so on
Your ajax request doesn't have a type and so will default to GET. add type : 'POST' if you want to use POST.
Try $_GET['co_subj_co']; instead of POST.
As long as you don't specify the method to jQuery's ajax call, it's made by GET, not POST.
I have annotated two things in the code:
$.ajax({
type : 'POST',
dataType: "json",
url:'config/forms/course_conf/course_generator.php',
data:{
co_subj_co:editedCourseId
}})
.done(function(newCourse){
var courseId = newCourse.newCourseId;
var newcourseName = newCourse.newCourseName;
var isMultisubjectValue = newCourse.isMultisubjectValue;
var subjectsNum = newCourse.subjectsNum;
var newCourseAbbrev = newCourse.newCourseAbbrev;
var newCourseTypeId = newCourse.newCourseTypeId;
var newCourseTypeName = newCourse.newCourseTypeName;
var newCourseStructure = '<div class="tableRow dynamicRow noHeight injectedRow"'
+ ' data-isMultisubjectValue="' + isMultisubjectValue + '"'
+ ' data-subjectsNum="' + subjectsNum + '"'
+ ' data-id="' + courseId + '"'
+ ' id="' + courseId + '"'
+ ' data-abbrev="' + newCourseAbbrev + '"'
+ ' data-courseTypeId="' + newCourseTypeId + '"'
+ ' title="' + newCourseName + '">'
+ '<div class="contentColumn40"><span class="tableContentText">'
+ newCourseName + ' (' + newCourseTypeName + ')</span></div>'
// WHERE IS subjectList DEFINED?
+ '<div class="contentColumn40">' + subjectList
+ '</div>'
+ '<div class="contentColumn10"><div class="tableIconLink">'
+ '<a href="#"><div class="editIcon" data-id="' + courseId + '"'
+ ' title="Editar ' + newCourseName + '"></div>'
+ '</a></div></div><div class="contentColumn10"><div class="tableIconLink">'
+ '<a href="#"><div data-id="'+courseId+'" class="discontinueIcon" '
+ 'title="Discontinuar '+newCourseName+'"></div></a></div></div></div>';
/*
* your HTML is generated, but you never put it in the DOM
*/
$('#idOutputWrapper').empty().html(newCourseStructure);
}
When you use subjectList from the json response, please notice that it comes with a closing </div> tag for some reason, maybe you should change that, too.
btw: Your code formatting is horrible, sorry to say so. You can compress your js before uploading it to the server, but while working on it, it NEEDS to be readable. I just edited it to fit better in the codeblock here.
Are you actually using POST, or are you firing off a GET request (your browser's developer tools should tell you this easily). You should also make sure that $courseId is an integer by $courseId = intval($_POST['co_cubj_co']);. In addition, you should add a condition for the event that the requested ID is not found.
As MueR suggests, the reason to make sure that courseID is an integer is to prevent SQL injection (unless you want people to do things like delete your entire DB at will). This, of course, assumes that courseID is something like an autoincrement int.
However, you've got a number of other problems. Your JSON is invalid since you're ostensibly writing out unquoted strings... you should just use json_encode:
$outArr = array();
$outArr['newCourseId'] = $result_co['co_id'];
$outArr['newCourseName'] = $result_co['co_name'];
...
echo json_encode($outArr);
Personally, I prefer to just use $_REQUEST, which concatenates both $_POST and $_GET. Makes it easier.
Could anyone please advise me of what am I doing wrong here?
I am trying to construct the image URL but using the flickr.photos.search method
now (I need to display images close to geolocation of the visitor), I had it
working before with groups_pool.gne and the JSON feed was different (simpler)
formatted but now..
The URL is working, I get the array with all the data I need (farm, server,
secret and id) but can't construct the url for the photo.
$.getJSON("http://api.flickr.com/services/rest/?method=flickr.photos.search&api_\
key=KEY&format=json&privacy_filter=0&media=photos&has_geo=1&accuracy=13&sort=int\
erestingness-desc&content_type=1&per_page=32&extras=geo,owner_name&page=1&radius\
_units=km&radius=1.521739&lat=40.952532&lon=-4.1326349999999366&text=Alcazar&jso\
ncallback=jsonp1320163051486", getJSONimages);
function getJSONimages(data) {
var htmlString = "";
$.each(data.photos.photo, function(i,item){
htmlString += '<img src="http://farm'+ item.farm +'.static.flickr.com/'+
item.server +'/'+ item.id +'_'+ item.secret +'_m.jpg" />';
});
$('#slideshow').html(htmlString);
Thank you.
I have added the url_m in the extras, in the URL to get the JSON feed and I get the full URL in my feed and that should help as I do not have to concatenate the rest but still doesn't work.
I can't get it to work, and it's extremely frustrating as I know is very simple.
Well, not for me obviously.
This is my function, after I get the url_m in the loop:
function getJSONimages(data) {
var htmlString = "";
$.each(data.photos.photo, function(i,item){
// var url = (item.url_m).replace("\", "");
htmlString += '<img src="' + item.url_m + '" />';
});
$('#slideshow').html(htmlString);
}
Even if I use the "url" variable or no, same result.
However, I have noticed something.
In the feed using groups_pool.gne, where I am able to pull the photos
successfully, I go to the media.m like that:
$.each(data.items, function(i,item){
var biggestSize = (item.media.m).replace("_m.jpg", ".jpg");
htmlString += '<img src="' + biggestSize + '" />';
Notice that I have items, then media, then m with it's own value! Is actually
items.[media: {m:PHOTOURL}].
Where as in this other JSON feed using the flickr.photos.search method, I have
the following "object path":
jsonFlickrApi.photos.photo[{url_m:PHOTOURL}]
And try to use this loop:
$.each(data.photos.photo, function(i,item){
htmlString += '<img src="' + item.url_m + '" />';
I think this is my problem but I don't have any ideas how to approach it. It's
obvious there is a different structure between the two feeds:
items.[media: {m:PHOTOURL}]
photos.photo[{url_m:PHOTOURL}]
I am going to research more on jQuery loops. Any ideas?
Weirdly these docs don't mention getting the farm. Can you console.log your item in the $.each loop and see what you get?
http://www.flickr.com/services/api/flickr.photos.search.html
It's clearly the right URL format though assuming you get all of those pieces:
http://www.flickr.com/services/api/misc.urls.html
EDIT
Can you tell me what this says (in the alert box):
$.each(data.photos.photo, function(i,item){
var url = 'http://farm'+ item.farm +'.static.flickr.com/' + item.server +'/'+ item.id +'_'+ item.secret +'_m.jpg';
alert(url);
});
A URL is not a JSON object so you cannot parse it.
You're trying get the URL parameters.
Include the following function and use it like this.
lat = querySt('lat');
lon = querySt('lon');
function querySt(ji) {
hu = window.location.search.substring(1);
gy = hu.split("&");
for (i=0;i<gy.length;i++) {
ft = gy[i].split("=");
if (ft[0] == ji) {
return ft[1];
}
}
}
You might want to modify this part
hu =window.location.search.substring(1);
to
hu = yourURLVariable;
if you're getting the URL from somewhere else.