Get children of children from xml file - javascript

so im trying to extract data from a xml file which looks like this:
<example>
<phrase>phrase1</phrase>
<word>
<definition>definition1</definition>
</word>
<word>
<definition>definition2</definition>
</word>
</example>
I want to be able to put definition1 and definition2 as seperate members of an array, for now i get them merged like this: definition1definition2
this is my code:
var $example = $xml.find("example");
$example.each(function(){
list.push($(this).children("word").children("definition").text());
});
Does anyone have an idea?
thanks

If you want to use JQuery, you need to change the
$example.each(function(){
list.push($(this).children("word").children("definition").text());
});
to
$example.children("word").children("definition").each(
function() {
list.push($(this).text());
});

Check out this Fiddle.
$(document).ready(function() {
var xml =
'<example>' +
'<phrase>phrase1</phrase>' +
'<word>' +
'<definition>definition1</definition>' +
'</word>' +
'<word>' +
'<definition>definition2</definition>' +
'</word>' +
'</example>' +
'';
var xmlDoc = new DOMParser().parseFromString(xml, 'text/xml');
var x = xmlDoc.documentElement.childNodes;
var list = [];
for (i = 0; i < x.length; i++) {
if (x[i].nodeName == 'word') {
console.log(x[i].childNodes[0].innerHTML);
list.push(x[i].childNodes[0].innerHTML);
}
}
document.getElementById('demo').innerHTML = list;
console.log(list);
});

jquery solution
$example.find("word > definition").map(function(){ return $(this).text()}).toArray()
var xml =
'<example>' +
'<phrase>phrase1</phrase>' +
'<word>' +
'<definition>definition1</definition>' +
'</word>' +
'<word>' +
'<definition>definition2</definition>' +
'</word>' +
'</example>' +
'';
var xmlDoc = new DOMParser().parseFromString(xml, 'text/xml');
var list = $("example > word > definition",xmlDoc).map(function(){ return $(this).text()}).toArray();
console.log(list);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
vanila js solution
// Code goes here
var list = [];
var txt = `<example>
<phrase>phrase1</phrase>
<word>
<definition>definition1</definition>
</word>
<word>
<definition>definition2</definition>
</word>
</example>`;
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 elements = xmlDoc.getElementsByTagName("definition");
[].forEach.call(elements, function(el) {
list.push(el.textContent)
});
console.log(list);

Related

How to improve extract xml node in javascript?

I have extract with regex split method, so i want to improve my code with proper xml extract method ?
XML format,
<SanctionLimit>
<SancionBy>50400003</SancionBy>
<MinimumLimit>0.01</MinimumLimit>
<MaximumLimit>9999999999.99</MaximumLimit>
</SanctionLimit>
here is what I am currently using:
$.each(DetailXmlData, function(indexData, objDetail) {
var xmlResult = objDetail.ParamInfo;
var arrSanction = [];
var Extracted_SancBy = [];
arrSanction = xmlResult.split("<MinimumLimit>")[0].replace("<SanctionLimit><SancionBy>", "").replace("</SancionBy><SancionBy>", ",").replace("</SancionBy>", "").split(",");
$.each(arrSanction, function(index, value) {
var sancLength = ctl00_ContentPlaceHolder1_chkSanctionedBy.getElementsByTagName('input').length;
for (var i = 0; i < sancLength; i++) {
if (ctl00_ContentPlaceHolder1_chkSanctionedBy.getElementsByTagName('span')[i].attributes["SanctionedByValue"].value == value) {
ctl00_ContentPlaceHolder1_chkSanctionedBy.getElementsByTagName('input')[i].checked = true;
}
}
});
txtMinimumLimit.value = xmlResult.split("</MinimumLimit>")[0].split("<MinimumLimit>")[1];
txtMaximumLimit.value = xmlResult.split("</MaximumLimit>")[0].split("<MaximumLimit>")[1];
txtRemarks.value = objDetail.ParamRemarks;
});
its work for me,
xmlDoc = $.parseXML(xmlResult),
$xml = $(xmlResult);
$($xml).each(function() {
alert("sanctioned By:" + $(this).find("SancionBy").text())
alert("Minimum Limit:" + $(this).find("MinimumLimit").text());
alert("MaximumLimit Limit:" + $(this).find("MaximumLimit").text());
});
why not use jquery's parseXML method?
var xml = $.parseXML(xmlcontent);
xml.find("tagName").text()

Splitting out xml result into dropdownlist

Hope someone can help - I'm new to js/jQuery so I'm hoping it's something really simple I'm missing here.
I'm trying to populate a dropdownlist with the xml result from below. The parseXML function works great and the result.push(valueid + "," + value) leaves me with the following:
1,Service
2,Breakdown
How do I get this into a dropdownlist please? Using the below, I get the error "Object doesn't support property or method 'split'"
Many thanks
leddy
function testFunction() {
var jobresults = "<resultset morerecords='0'> " +
"<result> " +
"<itt_jobtypeid>1</itt_jobtypeid> " +
"<itt_name>Service</itt_name> " +
"</result> " +
"<result> " +
"<itt_jobtypeid>2</itt_jobtypeid> " +
"<itt_name>Breakdown</itt_name> " +
"</result> " +
"</resultset> ";
var xml = parseXML(jobresults);
var jobid = xml.getElementsByTagName("itt_jobtypeid");
var jobname = xml.getElementsByTagName("itt_name");
var result = [];
for (var i = 0; i < jobid.length; i++) {
var valueid = jobid[i].childNodes[0].nodeValue;
var value = jobname[i].childNodes[0].nodeValue;
// add longitude value to "result" array
result.push(valueid + "," + value);
}
var jobtype = $("#ddlJobType");
$.each(result, function () {
var arr = result.split(',');
for (var i = 0; i < arr.length; i++) {
jobtype.append($("<option />").val(arr[0]).text(arr[1]));
}
});
}
function parseXML(text) {
if (window.DOMParser) {
parser = new DOMParser();
doc = parser.parseFromString(text, "text/xml");
}
else { // Internet Explorer
doc = new ActiveXObject("Microsoft.XMLDOM");
doc.async = "false";
doc.loadXML(text);
}
return doc;
}
It can be simpler and cleaner if you optimize data structure for result array. Push an object with value and label so that you can simply use attr method directly after:
for (var i = 0; i < jobid.length; i++) {
var valueid = jobid[i].childNodes[0].nodeValue;
var value = jobname[i].childNodes[0].nodeValue;
// add longitude value to "result" array
result.push({value: valueid, label: value});
}
var jobtype = $("#ddlJobType");
$.each(result, function (i, obj) {
$('<option>').attr(obj).appendTo(jobtype);
});
See https://api.jquery.com/jquery.each/. The callback function gets each jobtype as parameter to the function.
Try changing the code to:
$.each(result, function (idx, value) {
var arr = value.split(',');
for (var i = 0; i < arr.length; i++) {
jobtype.append($("<option />").val(arr[0]).text(arr[1]));
}
});

Javascript hoisting issue-first and second debug return different value

i tried to run a script for developing an add-on. Somehow, the first run will return undefined and only the second run will obtain the result i desire. I searched through and realised it might be something related with hoisting. Any ideas on this? Thanks.
var array1=[];
var array2=[];
var arrayPDS=[];
var arrayPD=[];
var suggPD;
function handleClick(state) {
var suggPD = Request({
url: "http://google.com/complete/search?output=toolbar&q=" + primarydomain,
overrideMimeType: "application/xml; charset=latin1",
onComplete: suggPDparse,
}).get();
function suggPDparse(response) {
var {Cc, Ci} = require("chrome");
var parser = Cc["#mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
var xml = parser.parseFromString(response.text, "application/xml");
var pds;
var pd = xml.getElementsByTagName("suggestion");
for (i=1;i<pd.length;i++){
pds = pd[i].getAttribute("data");
array1.push(pds);
arrayPDS = array1[0];
}
function loadXMLDoc(filename, callback){
var req = new XMLHttpRequest();
req.open("GET",filename,true);
req.onreadystatechange = function(){
if(req.readyState === 4){
callback(req.responseXML);
}
}
req.send();
}
loadXMLDoc(self.data.url("pd.xml"), function(xmlDoc){
if (xmlDoc.documentElement.nodeName=="parsererror"){
console.log(xmlDoc.documentElement.childNodes[0].nodeValue);
return(null);
}
var x = xmlDoc.getElementsByTagName("Row");
for (i=0; i<x.length; i++){
var a=x[i];
getV=(a.getElementsByTagName("Field_0")[0].childNodes[0].nodeValue);
array2.push(getV);
}
arrayPD = array2;
});
}
console.log("arrayPD: " + arrayPD);
console.log("arrayPDS: " + arrayPDS);
}
The result for first click will return:
arrayPD:
arrayPDS:
The result for second click will return:
arrayPD:abcd
arrayPDS:abcd

Javascript XML same element name

I have an XML file containing the same element name more than once, like below. I can only retrieve the first one. Would like to know how to retrieve all 4 "comments" using JavaScript. Thanks!
<FRIENDSSTATUS>
<STATUSFRIENDS id="2">
<STATUS>Life begins at the end of your comfort zone</STATUS>
<DATETIME>2012-10-30 10:32:28</DATETIME>
<FIRSTNAME>Malcolm</FIRSTNAME>
<LASTNAME>Landgraab</LASTNAME>
<COMMENTS datetime="2012-11-18 22:13:28" firstname="Ian" lastname="Tellerman">rr</COMMENTS>
<COMMENTS datetime="2012-11-18 22:13:39" firstname="Ian" lastname="Tellerman">hello</COMMENTS>
<COMMENTS datetime="2012-11-19 14:36:24" firstname="Ian" lastname="Tellerman">test</COMMENTS>
<COMMENTS datetime="2012-11-19 14:45:52" firstname="Ian" lastname="Tellerman">test4</COMMENTS>
</STATUSFRIENDS>
<STATUSFRIENDS id="3">
<STATUS>Prometheus. Fantastic film!!!!</STATUS>
<DATETIME>2012-10-30 10:32:28</DATETIME>
<FIRSTNAME>Mansa</FIRSTNAME>
<LASTNAME>Bendett</LASTNAME>
<COMMENTS datetime="2012-11-18 22:14:46" firstname="Ian" lastname="Tellerman">wrong</COMMENTS>
</STATUSFRIENDS>
</FRIENDSSTATUS>
The javascript codes:
xmlDoc = xmlhttp.responseXML;
$table = "<table border='1'>";
var element = xmlDoc.getElementsByTagName("FRIENDSSTATUS");
var elements = xmlDoc.getElementsByTagName("STATUSFRIENDS");
var comments = xmlDoc.getElementsByTagName("COMMENTS");
if(xmlDoc.documentElement !== null)
{
var root;
if (navigator.userAgent.indexOf("Firefox") > 0 )
var root = element[0].childElementCount;
if (navigator.userAgent.indexOf("MSIE") > 0 )
var root = xmlDoc.documentElement.childNodes.length;
for(i=0; i<root; i++){
$strStats = "";
$strComments = "";
$strDateTime = "";
$strFirstname = "";
$strLastname = "";
$strCommentDateTime = "";
$strCommentFirstName = "";
$strCommentLastName = "";
$strStatusID = "";
if(navigator.userAgent.indexOf("Firefox") > 0 ){
for(y=0;y < elements[i].childElementCount;y++)
{
$strStatusID = elements[i].getAttribute("id");
if(strStatus = elements[i].getElementsByTagName("STATUS"))
{
$strStats = strStatus[0].firstChild.nodeValue;
}
if(strStatus = elements[i].getElementsByTagName("DATETIME"))
{
$strDateTime = strStatus[0].firstChild.nodeValue;
}
if(strStatus = elements[i].getElementsByTagName("FIRSTNAME"))
{
$strFirstname = strStatus[0].firstChild.nodeValue;
}
if(strStatus = elements[i].getElementsByTagName("LASTNAME"))
{
$strLastname = strStatus[0].firstChild.nodeValue;
}
if(strComm = elements[i].getElementsByTagName("COMMENTS"))
{
$strComments = strComm[0].firstChild.nodeValue;
$strCommentDateTime = comments[i].getAttribute("datetime");
$strCommentFirstName = comments[i].getAttribute("firstname");
$strCommentLastName = comments[i].getAttribute("lastname");
$strComments += "<br>" + $strCommentFirstName + " " + $strCommentLastName + " " + $strCommentDateTime + "</br></br>";
}
$strStats = $strStats + " " + $strLastname + " " + $strFirstname + " " + $strDateTime;
$strFullName = $strFirstname + " " + $strLastname;
$strDateTime = "";
$strFirstname = "";
$strLastname = "";
}
}
Assign your XML to a variable, (myXmlString in this example), and read it as follows:
var parser=new DOMParser();
doc=parser.parseFromString(myXmlString,'text/xml');
var comments = doc.getElementsByTagName("COMMENTS") // Returns a array of those "comments".
An example of how to access the comments of the first STATUSFRIENDS. jsFiddle demo here.
var parseXml;
if (typeof window.DOMParser != "undefined") {
parseXml = function(xmlStr) {
return ( new window.DOMParser() ).parseFromString(xmlStr, "text/xml");
};
} else if (typeof window.ActiveXObject != "undefined" &&
new window.ActiveXObject("Microsoft.XMLDOM")) {
parseXml = function(xmlStr) {
var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = "false";
xmlDoc.loadXML(xmlStr);
return xmlDoc;
};
} else {
throw new Error("No XML parser found");
}
var xml = parseXml(xmlStr); // assuming xmlStr contains your XML
var commentsList = xml.documentElement.childNodes[0].getElementsByTagName("COMMENTS");
var output = "";
for(var i=0; i<commentsList.length; i++)
{
output += commentsList[i].firstChild.nodeValue + "<br />";
}
document.getElementById("comments").innerHTML = output;
Something like this:
var str = 'your XML as a string',
parser, xml;
if (window.DOMParser) {
parser = new DOMParser();
xml = parser.parseFromString(str, "text/xml");
}
else { // IE
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = "false";
xml.loadXML(str);
}
var nodes = xml.childNodes[0].getElementsByTagName('COMMENTS');
var i, l = nodes.length, comments = [];
for (i = 0; i < l; i++) {
comments.push({
firstname: nodes[i].getAttribute('firstname'),
lastname: nodes[i].getAttribute('lastname'),
datetime: nodes[i].getAttribute('datetime'),
content: nodes[i].childNodes[0].nodeValue
});
}
console.log(comments);
I don't have time to post a full code sample, but JS supports XPath and you can get the Comments with this Qpath query:
/FRIENDSSTATUS/STATUSFRIENDS[#id="3"]/COMMENTS
Here is where I tested the Xpath syntax: http://chris.photobooks.com/xml/default.htm

How to parse XML string with Prototype?

I have a string <ul><li e="100" n="50">Foo</li><li e="200" n="150">Bar</li></ul> and on client side I have to convert it to JSON. Something like {data:['Foo','Bar'],params:['100;50','200;150']}
I found a pretty good way to achieve it in here so my code should be something like that
var $input = $(input);
var data = "data:[";
var params = "params:[";
var first = true;
$input.find("li").each(function() {
if (!first) {
data += ",";
params += ",";
} else {
first = false;
}
data += "'" + $(this).text() + "'";
var e = $(this).attr("e");
var n = $(this).attr("n");
params += "'" + e + ';' + n + "'";
});
return "{data + "]," + params + "]}";
But the problem is that I can't use jquery. How can I do the same thing with prototype?
You want to use a DOM parser:
https://developer.mozilla.org/en/DOMParser
Something like this...
var xmlStr = '<ul><li e="100" n="50">Foo</li><li e="200" n="150">Bar</li></ul>';
var parser = new DOMParser();
var doc = parser.parseFromString(xmlStr, "application/xml");
var rootElement = doc.documentElement;
var children = rootElement.childNodes;
var jsonObj = {
data: [],
params: []
};
for (var i = 0; i < children.length; i++) {
// I realize this is not how your implementation is, but this should give
// you an idea of how to work on the DOM element
jsonObj.data.push( children[i].getAttribute('e') );
jsonObj.params.push( children[i].getAttribute('n') );
}
return jsonObj.toJSON();
Also, don't manually build your JSON string. Populate an object, then JSON-encode it.
Edit: Note that you need to test for DOMParser before you can use it. Check here for how you can do that. Sorry for the W3Schools link.
Why you are building an array object with string? Why not
var data = new Array();
var params = new Array();
$$("li").each(function() {
data.push ($(this).text());
params.psuh($(this).attr("e") + ";" + $(this).attr("n"));
});
return {data:data.toString(), params:params.toString()};
or
return {data:data, params:params};

Categories