I'm using an XMLHttpRequest to retrieve XML from the server, and I'd like to append it to an existing HTML node on the page. It's well formed HTML and I've added xmlns='http://www.w3.org/1999/xhtml' to the XML root element in the response: works fine for Firefox, but IE bombs with "No such interface supported", I guess because it's got the node I'm trying to append typed as "IXMLDOMElement".
Here's the XML response:
<qstat xmlns='http://www.w3.org/1999/xhtml'>
<ul>
<li><b>Cycle number:</b> 6</li>
<li><b>Error:</b> none</li>
</ul>
</qstat>
And here's the Javascript:
var req = new XMLHttpRequest()
req.onreadystatechange = function() {
if(req.readyState == 4)
{
dom = req.responseXML;
var nodes = dom.firstChild.childNodes; //Everything under the root node.
var ele = document.getElementById("qstat");
for(var i=0; i<nodes.length; i++)
{
ele.appendChild(nodes[i]); // BOMBS HERE.
}
}
};
The MSIE Debugger (MSIE 8) correctly identifies nodes[0] as having tagName=ul and even has namespaceURI="http://www.w3.org/1999/xhtml", but I guess because it's type is IXMLDOMElement, the call doesn't work.
So is there any way to convert the objects in nodes to corresponding HTML node objects that I can append to the element?
Try following:
1) create an HTML element
var factory = document.createElement("div");
2) serialize the fetch XML element
var xml = nodes[i].xml || new XMLSerializer().serializeToString(nodes[i]);
3) render xml through innerHTML
factory.innerHTML = xml;
4) get firstChild from factory element which is now HTML element
var eleHTML = factory.firstChild;
5) append eleHTML to where you need it:
ele.appendChild(eleHTML);
Hint: you can reuse once created factory DOMHTML element
Related
Is there a way to convert HTML like:
<div>
<span></span>
</div>
or any other HTML string into DOM element? (So that I could use appendChild()). I know that I can do .innerHTML and .innerText, but that is not what I want -- I literally want to be capable of converting a dynamic HTML string into a DOM element so that I could pass it in a .appendChild().
Update: There seems to be confusion. I have the HTML contents in a string, as a value of a variable in JavaScript. There is no HTML content in the document.
You can use a DOMParser, like so:
var xmlString = "<div id='foo'><a href='#'>Link</a><span></span></div>";
var doc = new DOMParser().parseFromString(xmlString, "text/xml");
console.log(doc.firstChild.innerHTML); // => <a href="#">Link...
console.log(doc.firstChild.firstChild.innerHTML); // => Link
You typically create a temporary parent element to which you can write the innerHTML, then extract the contents:
var wrapper= document.createElement('div');
wrapper.innerHTML= '<div><span></span></div>';
var div= wrapper.firstChild;
If the element whose outer-HTML you've got is a simple <div> as here, this is easy. If it might be something else that can't go just anywhere, you might have more problems. For example if it were a <li>, you'd have to have the parent wrapper be a <ul>.
But IE can't write innerHTML on elements like <tr> so if you had a <td> you'd have to wrap the whole HTML string in <table><tbody><tr>...</tr></tbody></table>, write that to innerHTML and extricate the actual <td> you wanted from a couple of levels down.
Why not use insertAdjacentHTML
for example:
// <div id="one">one</div>
var d1 = document.getElementById('one');
d1.insertAdjacentHTML('afterend', '<div id="two">two</div>');
// At this point, the new structure is:
// <div id="one">one</div><div id="two">two</div>here
Check out John Resig's pure JavaScript HTML parser.
EDIT: if you want the browser to parse the HTML for you, innerHTML is exactly what you want. From this SO question:
var tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlString;
Okay, I realized the answer myself, after I had to think about other people's answers. :P
var htmlContent = ... // a response via AJAX containing HTML
var e = document.createElement('div');
e.setAttribute('style', 'display: none;');
e.innerHTML = htmlContent;
document.body.appendChild(e);
var htmlConvertedIntoDom = e.lastChild.childNodes; // the HTML converted into a DOM element :), now let's remove the
document.body.removeChild(e);
Here is a little code that is useful.
var uiHelper = function () {
var htmls = {};
var getHTML = function (url) {
/// <summary>Returns HTML in a string format</summary>
/// <param name="url" type="string">The url to the file with the HTML</param>
if (!htmls[url])
{
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", url, false);
xmlhttp.send();
htmls[url] = xmlhttp.responseText;
};
return htmls[url];
};
return {
getHTML: getHTML
};
}();
--Convert the HTML string into a DOM Element
String.prototype.toDomElement = function () {
var wrapper = document.createElement('div');
wrapper.innerHTML = this;
var df= document.createDocumentFragment();
return df.addChilds(wrapper.children);
};
--prototype helper
HTMLElement.prototype.addChilds = function (newChilds) {
/// <summary>Add an array of child elements</summary>
/// <param name="newChilds" type="Array">Array of HTMLElements to add to this HTMLElement</param>
/// <returns type="this" />
for (var i = 0; i < newChilds.length; i += 1) { this.appendChild(newChilds[i]); };
return this;
};
--Usage
thatHTML = uiHelper.getHTML('/Scripts/elevation/ui/add/html/add.txt').toDomElement();
Just give an id to the element and process it normally eg:
<div id="dv">
<span></span>
</div>
Now you can do like:
var div = document.getElementById('dv');
div.appendChild(......);
Or with jQuery:
$('#dv').get(0).appendChild(........);
You can do it like this:
String.prototype.toDOM=function(){
var d=document
,i
,a=d.createElement("div")
,b=d.createDocumentFragment();
a.innerHTML=this;
while(i=a.firstChild)b.appendChild(i);
return b;
};
var foo="<img src='//placekitten.com/100/100'>foo<i>bar</i>".toDOM();
document.body.appendChild(foo);
Alternatively, you can also wrap you html while it was getting converted to a string using,
JSON.stringify()
and later when you want to unwrap html from a html string, use
JSON.parse()
I'm trying to append XML node to HTML DOM in IE <8 and I keep getting Object doesn't support property or method appendChild error but works fine on latest browsers. Is there another way of appending XML element in DOM?
I also tried putting <meta http-equiv="X-UA-Compatible" content="IE=8">
I want to append XML element not as string like the image below.
var jObj = { "Smart Shoes":{
"Product":"Smart Shoes",
"Price":24.99,
"Quantity":"1x "
},
"Denim Jeans":{
"Product":"Denim Jeans",
"Price":30,
"Quantity":"1x "
}
};
var xml = document.createElement("xml");
xml.setAttribute("id", "POSCMD");
xml.setAttribute("LateProcessing", "true");
var commands = document.createElement("commands");
xml.appendChild(commands);
var injFM = document.createElement("injectfieldmacro");
injFM.setAttribute("type", "field");
injFM.setAttribute("name", "FIELD_CLEAR");
commands.appendChild(injFM);
var injData;
for (var item in jObj) {
injData = document.createElement("injectdata");
injData.setAttribute("type", "literal");
injData.setAttribute("data", JSON.stringify(jObj[item].Product));
injFM = document.createElement("injectfieldmacro");
injFM.setAttribute("type", "field");
injFM.setAttribute("name", "FIELD_UPC");
commands.appendChild(injData);
commands.appendChild(injFM);
}
document.getElementsByTagName("body")[0].appendChild(xml);
I'm trying to display data from the xml file by first getting the content of the xml file and storing it in XML DOM. Once the DOM object is created it is then parsed. I used a for loop so as to get data from each child node of the parent node but somehow only the second node's data is showing.
This is the code where the error is:
xmlhttp.open("GET","company.xml", false); //sets the request for calling company.xml
xmlhttp.send(); //sends the request
xmlDoc = xmlhttp.responseXML; //sets and returns the content as XML DOM
//parsing the DOM object
var employeeCount = xmlDoc.getElementsByTagName("Employee");
for(i=0; i<employeeCount.length; i++)
{
document.getElementById("firstName").innerHTML = xmlDoc.getElementsByTagName("FirstName")[i].childNodes[0].nodeValue;
document.getElementById("lastName").innerHTML = xmlDoc.getElementsByTagName("LastName")[i].childNodes[0].nodeValue;
document.getElementById("contactNum").innerHTML = xmlDoc.getElementsByTagName("ContactNo")[i].childNodes[0].nodeValue;
}
The XML file:
<?xml version="1.0"?>
<Company>
<Employee category="technical">
<FirstName>Tanmay</FirstName>
<Nickname>Tania</Nickname>
<LastName>Patil</LastName>
<ContactNo>1234567890</ContactNo>
</Employee>
<Employee category="non-technical">
<FirstName>Taniya</FirstName>
<LastName>Mishra</LastName>
<ContactNo>1234667898</ContactNo>
</Employee>
</Company>
This the output:
How can i display the data from node [0] as well? Any suggestions will be appreciated. Thanks.
The problem is that you're overwriting data from previous Employee on every iteration :
for(i=0; i<employeeCount.length; i++)
{
document.getElementById("firstName").innerHTML = xmlDoc.getElementsByTagName("FirstName")[i].childNodes[0].nodeValue;
document.getElementById("lastName").innerHTML = xmlDoc.getElementsByTagName("LastName")[i].childNodes[0].nodeValue;
document.getElementById("contactNum").innerHTML = xmlDoc.getElementsByTagName("ContactNo")[i].childNodes[0].nodeValue;
}
That's why only the last Employee data remains in innerHTMLs in the end.
I want to convert an xml element like this:
<asin>B0013FRNKG</asin>
to string in javascript
I used XMLSerializer:
new XMLSerializer().serializeToString(xml);
the string only shows on alert() and in the console. On the page it just says
[object Element][object Element]
I want to get the string.
You haven't told us how you go about displaying that object. XMLSerializer works on DOM nodes, so your object has to be added somewhere, for example:
document.getElementById('SomeDiv').appendChild(xml);
and if you just want the full xml string to be displayed:
var xmlText = new XMLSerializer().serializeToString(xml);
var xmlTextNode = document.createTextNode(xmlText);
var parentDiv = document.getElementById('SomeDiv');
parentDiv.appendChild(xmlTextNode);
<script type='text/javascript'>
function xmlToString(xmlData) {
var xmlString;
//IE
if (window.ActiveXObject){
xmlString = xmlData.xml;
}
// code for Mozilla, Firefox, Opera, etc.
else{
xmlString = (new XMLSerializer()).serializeToString(xmlData);
}
return xmlString;
}
</script>
use this in case of IE for browser compatibility issues.
function getXmlString(xml) {
if (window.ActiveXObject) { return xml.xml; }
return new XMLSerializer().serializeToString(xml);
}
alert(getXmlString(xml));
Did you try enclosing the result like in…
(new XMLSerializer()).serializeToString(xml)
Also, I'd use console instead to see the content better:
console.log((new XMLSerializer()).serializeToString(xml));
If the DOM element <asin>B0013FRNKG</asin> is stored in the object element, then you can access the value using:
element.textContent
follow this to print,append data from xml data stored as string inside javscript
txt="<papers>"+"<paper>"+
"<author>athor name</author>"+
"<title>title</title>"+
"<path>path</path>"+
"<track>which tack</track>"+
"</paper>"+
"<paper>"+
"<author>athor name</author>"+
"<title>title</title>"+
"<path>path</path>"+
"<track>which tack</track>"+
"</paper>"+
"<paper>"+
"<author>athor name</author>"+
"<title>title</title>"+
"<path>path</path>"+
"<track>which tack</track>"+
"</paper>"+
"<papers>";
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);
}
x=xmlDoc.getElementsByTagName("paper");
for (var i = 0; i < x.length; i++) {
var athor =x[i].childNodes[0].firstChild.nodeValue;
var title = x[i].childNodes[1].firstChild.nodeValue;
var path = x[i].childNodes[2].firstChild.nodeValue;
var tack =x[i].childNodes[3].firstChild.nodeValue;
//do something with these values...
//each iteration gives one paper details
var xml=document.getElementById("element_id");//<div id="element_id"></div>
var li = document.createElement("br");// create a new <br>
newlink = document.createElement('A'); // creating an <a> element
newlink.innerHTML = athor;// adding <a>athor value here</a>
newlink.setAttribute('href', path);//
newlink.appendChild(li);// athor<br>
document.getElementById("element_id").appendChild(newlink);//finaly it becomes <div id="element_id">athor<br></div>
}
How do i loop through the 'roster' tag, and push in to an array, if any 'player' node is found .
How do i check, no child elements in 'roster' tag .
I tried in the following way, but not working,
var strXML = '<root><club><roster/></club>\
<club><roster>
<player code="AUQ" name="AVDALOVIC, VULE" position="Guard"/>\
<player code="AQX" name="SCHULTZE, SVEN" position="Forward"/>\
</roster></club></root>';
var p = new DOMParser();
var doc = p.parseFromString(strXML, "application/xml");
var players=doc.getElementsByTagName("player");
var i=0,arr=[];
for(i=0;i<players.length;i++){
arr.push({
code:players[i].getAttribute("code"),
name:players[i].getAttribute("name"),
position:players[i].getAttribute("position"),
});
}
console.log(arr);
I am getting the output, but the output is coming blank, if any blank values are found.
Your xml has a problem, there should be one root element for the document
var strXML = '<root><club><roster/></club><club><roster><player code="AUQ" name="AVDALOVIC, VULE" position="Guard"/><player code="AQX" name="SCHULTZE, SVEN" position="Forward"/></roster></club></root>';
Demo: Fiddle