clonoNode() Dom method unable to Clone given Xml Doc Object - javascript

When i trying to Clone Xml Document Object Chrome,IE behaves properly but Safari Browser version 5.1.7 which returns null,
Follwing is my sample Code
xml string
var xmlStr="<tr> <td class="dsd"> </td><td class='name'></td></tr>"
var doc=getXmlDoc(xmlStr) (i.e getXmlDoc is my custom function which returns string to doc using DOM Parser)
funtion getXmlDoc(str)
{
parser = new DOMParser();
xmlDoc = parser.parseFromString(str,"text/xml");
return xmlDoc
}
doc-Document(converted Document)
d.cloneNode(true)-Returns null
When i try to clone Entire Document,unable to clone
But d.documentElement.cloneNode(true) works
But when i try to clone root node , i can.
This Issue only in Safari Browser 5.1.7 Tested.
I am working on ExtJs Framework, where EXt.clone() also returns null
Thanks in advance,
Praveenkumar

Since Safari doesnt clone the Entire Document, but it still clone(supports) documentElement . For Example
var xmlStr="<tr> <td class="dsd"> </td><td class='name'></td></tr>";
//convert the above string into document
//funtion getXmlDoc(str)
{
parser = new DOMParser();
xmlDoc = parser.parseFromString(str,"text/xml");
return xmlDoc
}
var newDoc=getXmlDoc(str);
//after Converting str to newDoc
var copy=newDoc.cloneNode(true);//will return error
//Let see How to Done
var copy=getXmlDoc(getXmlStr(newDoc.documentElement.cloneNode(true)));
Explanation
CloneNode method clones a given element, but we need to clone a document so, first we clone elements and convert them string then convert them Doc.
But it seems little memory consuming,
anyhow anyone provide better solution.

Related

How to find multiple different matches using regex in Javascript? [duplicate]

var html = '<p>sup</p>'
I want to run document.querySelectorAll('p') on that text without inserting it into the dom.
In jQuery you can do $(html).find('p')
If it's not possible, what's the cleanest way to to do a temporary insert making sure it doesn't interfere with anything. then only query that element. then remove it.
(I'm doing ajax requests and trying to parse the returned html)
With IE 10 and above, you can use the DOM Parser object to parse DOM directly from HTML.
var parser = new DOMParser();
var doc = parser.parseFromString(html, "text/html");
var paragraphs = doc.querySelectorAll('p');
You can create temporary element, append html to it and run querySelectorAll
var element = document.createElement('div');
element.insertAdjacentHTML('beforeend', '<p>sup</p>');
element.querySelectorAll('p')

Parse HTML String to DOM and convert it back to string

I've got an HTML string e.g. '<p><span class="text">Hello World!</span></p>'
I parse this HTML string to DOM using DOMParser().parseFromString(), because I want to change the innerHTML of some specific elements. That's why I parse the HTML string to DOM and with getElementByClassName I get all my elements and loop through them to change it innerHTML. This works so far.
After I changed the innerHTML, I try to convert the new DOM back to a string. I can't figure out how. What I tried is to assign the innerHTML or outerHTML (tried both) to a variable like this:
const parser = new DOMParser();
const doc = parser.parseFromString("<p>Hello World!</p>", "text/html");
console.log(doc.innerHTML) // undefined
console.log(doc.outerHTML) // undefined
const parser = new DOMParser();
const doc = parser.parseFromString("<p>Hello World!</p>", "text/html");
console.log(doc.innerHTML) // undefined
console.log(doc.outerHTML) // undefined
I always get undefined. How can I parse it back to a string? I found a lot examples with innerHTML or outerHTML, but in my case something went wrong. Any ideas?
DOMParser will always give you a document in return. Documents don't have an innerHTML property, but the document.documentElement does, just like in a page's normal document object:
const myHtmlString = '<p><span class="text">Hello World!</span></p>'
const htmlDom = new DOMParser().parseFromString(myHtmlString, 'text/html');
console.log(htmlDom.documentElement.innerHTML);
Do note that a <head> and <body> will be created for you, if you don't pass those tags in yourself. If you only want the body, then:
const myHtmlString = '<p><span class="text">Hello World!</span></p>'
const htmlDom = new DOMParser().parseFromString(myHtmlString, 'text/html');
console.log(htmlDom.body.innerHTML);

How to convert from a DOM Object to html?

I have taken a string of html in and have converted it to a DOM Object.
document.getElementById("textarea").value
var parser = new DOMParser();
var html = parser.parseFromString(htmlString, 'text/html');
How do I take the DOM Object that I created and convert it back to html? Could you please show an example how I could put it on an html page?
From the HTMLDocument that parseFromString() gives you, you can retrieve the its documentElement and then that element's innerHTML.
console.log(html.documentElement.innerHTML);
Note that the markup may become normalized to make it a valid document, so you may end with more than you started:
var markup = '<span>Foo</span>';
var parser = new DOMParser();
var doc = parser.parseFromString(markup, 'text/html');
console.log(doc.documentElement.innerHTML);
// "<head></head><body><span>Foo</span></body>"
Or, have corrections made for you:
var markup = '<table><div>Foo</div></table>';
// ...
console.log(doc.documentElement.innerHTML);
// "<head></head><body><div>Foo</div><table></table></body>"
You seem to be creating an entire Document, not sure if that is intentional. But, this should work with that you have now:
var parser = new DOMParser();
var html = parser.parseFromString('<b>ok</b>', 'text/html');
document.write(html.body.innerHTML);

XML Parsing vs DOM Implementation create methods

I remember well that using the DOM implementation to create new HTML elements on a document was considered to be very much slower than assigning an HTML string to the 'innerHTML' property of the applicable HTML element.
Does the same apply when authoring XML documents using JavaScript? Rather than using the DOM implementation's various create methods, would it be faster to just generate the XML string and parsing it?
Just something I wondered about.... :)
*EDIT - Added an example *
Which is faster? (I'll be using jQuery's parseXML function to do the parsing example):
var myXdoc = $.parseXML("<person><name>Bob</name><relation>Uncle</relation>");
Or
var myXdoc
if (window.ActiveXObject) {
myXdoc = new ActiveXObject("Microsoft.XMLDOM");
myXdoc.async = false;
}
else if (document.implementation && document.implementation.createDocument)
myXdoc = document.implementation.createDocument("", "", null);
var p = myXdoc.documentElement.appendChild(myXdoc.createElement("person"));
var n = p.appendChild(myXdoc.createElement("name"));
n.appendChild(myXdoc.createTextNode("Bob"));
var r = p.appendChild(myXdoc.createElement("relation"));
r.appendChild(myXdoc.createTextNode("Uncle"));
The first thing we have to know why createDocument() might be slow. The reason is that the DOM is alive and if you are modifying it, it triggers a re-validation of the DOM tree and probably a redraw of the site. Every time. But we could avoid this unnecessary re-validation and re-draw by using createDocumentFragment(). The DocumentFragment isn't part of the DOM and so it wont trigger any events. So you can build your complete DOM part and in the last step append it to the DOM tree. I think it's the fastest way to create large DOM parts.
UPDATE
I tested it in Firefox 7 using Firebug. The code:
console.time("a");
for(var i=0; i<1000; i++) {
$.parseXML("<person><name>Bob</name><relation>Uncle</relation></person>")
}
console.timeEnd("a");
console.time("b");
for(var i=0; i<1000; i++) {
var myXdoc
if (document.createDocumentFragment) {
myXdoc = document.createDocumentFragment();
}
var p = myXdoc.appendChild(document.createElement("person"));
var n = p.appendChild(document.createElement("name"));
n.appendChild(document.createTextNode("Bob"));
var r = p.appendChild(document.createElement("relation"));
r.appendChild(document.createTextNode("Uncle"));
}
console.timeEnd("b");
The result: "a" about 140ms and "b" about 35ms. So the string parse version is slower.
UPDATE2
It's very likely that the second variant is faster in any other browser, too. Because the parse method has to build the DOM object too and it's very likely that it uses the same methods (e.g.: document.createElement). So the parse method can't be faster. But it's slower because it has first to parse the string.

Why does this Javascript DOM code only working FF, but not IE?

//create an instance of the XML parser
if (window.ActiveXObject)
{
//Checking if the browser is IE
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false"; //make sure doc is fully loaded
xmlDoc.load(strPath) //load the file in the parser
if (xmlDoc.parseError.errorCode != 0)
{
alert("Error #: " + xmlDoc.parseError.errorCode;
}
}
//for mozilla based browsers
else if (document.implementation && document.implementation.createDocument)
{
xmlDoc= document.implementation.createDocument("","doc",null);
xmlDoc.async=false; //make sure doc is fully loaded
loaded = xmlDoc.load(strPath);
if(!loaded)
{
alert("Error in XML File");
}
}
//Parse the XML
var root = xmlDoc.documentElement;
level1Nodes = root.children;
for(var index1 = 0; index1 < level1Nodes.length; index1++)
{
//Extract the markup content from XML
var level1Node = level1Nodes[index1];
var strName = level1Node.children[0].textContent;
var strHeader1 = level1Node.children[1].tagName;
var strHeader1Content = level1Node.children[1].textContent;
}
Is the "children" property available in the IE DOM Parser?
In IE, an XML document does not implement the same document object model as an HTML document; in particular, XML Node objects don't have the children property, which is non-standard.
You should use the childNodes collection instead. However be aware that in Firefox and other browsers - and, IIRC, under very specific circumstances in IE - this collection will also include text nodes that contain only whitespace, such as line breaks in the original XML file. So you will need to check the nodeType property: if it has the value 1, it is an Element, and will have properties such as tagName.
Furthermore, as MSXML implements DOM Level 1, whereas Firefox implements DOM Level 3, you won't be able to use the textContent property, which was introduced in Level 3. Instead, you will have to iterate over the childNodes of nodeType === 3 and concatenate their nodeValue properties, and probably then will want to trim any leading or trailing whitespace. Alternatively, if you know that there will only ever be textNodes in there, call the normalize method of the element first to make sure it only has one text node child.
Nobody ever said this stuff was supposed to be easy :-(
children is an object in IE6. Perhaps there's an inconsistency in that IE's first child is a text node, whereas in other browsers the first child is a DOM element node? Usually you'd use .childNodes and .childNodes.length and check for .nodeType==1 in a loop to run through the children.

Categories