Parse HTML String to DOM and convert it back to string - javascript

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);

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')

Why am I getting a {"location": null} when I try to convert a text/xml into an object?

I'm trying to understand the DOMParser behavior, but something is going wrong and I'm not knowing how to find the problem. Here's a simple code that parses a string that contains the text of an XML:
const xml = '<data>Hello World</data>'
const parser = new DOMParser()
const result = parser.parseFromString(xml, 'text/xml')
alert(JSON.stringify(result))
As you can see, I'm getting a {"location": null}. Can someone explain to me what's wrong and what is this location? How can I parse this string into an object as the documentation suggests?
The Document returned from parseFromString() is not JSON, if you want to stringify the result, use an XMLSerializer.
const xml = '<data>Hello World</data>';
const doc = new DOMParser().parseFromString(xml, 'text/xml');
const docString = new XMLSerializer().serializeToString(doc);
console.log(docString);
parseFromString returns the document object that holds the parsed representation of text, like:
const xml = '<data>Hello World</data>'
const parser = new DOMParser()
const result = parser.parseFromString(xml, 'text/xml')
console.log(result)
You can see the complete object in the console.log(). As per your concerned about where the "location": null comes from so It is currently unclear what the URL of the returned document should be.
You can learn more about parseFromString from here.
Please use following script:-
Html-
<p id="demo"></p>
Javascript -
<script>
var parser, xmlDoc;
var text = "<data>Hello`enter code here` World</data>";
parser = new DOMParser();
xmlDoc = parser.parseFromString(text,"text/xml");
document.getElementById("demo").innerHTML =
xmlDoc.getElementsByTagName("data")[0].childNodes[0].nodeValue;
</script>
It works as you want.
From the Documentation-
The DOMParser interface provides the ability to parse XML or HTML
source code from a string into a DOM Document.
So, it is converting XML or HTML to DOM Document, not JSON. For, this reason the result couldn't show any result by alert(JSON.stringify(result))
const xml = '<data>Hello World</data>'
const parser = new DOMParser()
const result = parser.parseFromString(xml, 'text/xml')
console.log(result);
Output:
#Document
<data>Hello World</data>
For your expected result, use XMLSerializer
let s = new XMLSerializer();
console.log(s.serializeToString(result));

How to update a parsed xml value

I'm parsing an XML as an object and accessing nodes by tagname, I have a problem where the value I'd like to see updated doesn't get updated. The alert shows me the value and it is correct. But i need it to be displayed on the document and which it isn't.
var x = xml.responseXML;
var v1 = document.getElementById("sid");
alert(x.getElementsByTagName("ID")[0].childNodes[0].nodeValue);
v1.innerText = x.getElementsByTagName("ID")[0].childNodes[0].nodeValue;
I also have a question of how can I allow editing/highlight of the node?
If nodeValue is null, setting its value has no effect (from the docs). However, you can modify the XML content in other ways, for example .innerHTML, .innerText, .value and more. Example with .innerHTML:
// creates a Document, as in XMLHttpRequest.responseXML
const docText = `
<!DOCTYPE html>
<body>
<div>Hello</div>
<div>World</div>
</body>`;
const doc = (new DOMParser()).parseFromString(docText, 'application/xml');
// setting nodeValue over null has no effect...
console.log(doc.getElementsByTagName('div')[0].nodeValue);
doc.getElementsByTagName('div')[0].nodeValue = 'Bye';
console.log(doc.getElementsByTagName('div')[0].nodeValue);
// ...but you can modifies the XML in different ways
console.log(doc.getElementsByTagName('div')[0].innerHTML);
doc.getElementsByTagName('div')[0].innerHTML = 'Bye';
console.log(doc.getElementsByTagName('div')[0].innerHTML);

How can I parse a string representation of an element into an actual html element?

For example, if I have:
'<html><body><p>hello</p></body></html>'
How can I parse this into an actual html element?
I've tried something like below:
getNodeType(element) {
const temp = document.createElement('div');
temp.innerHTML = element;
if (temp.firstChild) return temp.firstChild.nodeName;
else return null;
}
Which works pretty well, but I am unable to parse tags such as <html>, <body>, and <title> because they are unable to be contained in a div. I've also tried DOMParser but it wraps everything in html, head, and body tags, so I can't identify the actual element.
Would prefer to not use jQuery, but not completely opposed to it.
Any advice is greatly appreciated, thanks very much!
You should use DOMParser for this purpose:
parser = new DOMParser();
doc = parser.parseFromString('<html><body><p>hello</p></body></html>', 'text/html');
console.log(doc.getElementsByTagName('p')[0])
// will print: <p>hello</p>
More info here: https://developer.mozilla.org/en/docs/Web/API/DOMParser
Not sure why you had issues with DOMParser, it should work fine
const parser = new DOMParser();
const doc = parser.parseFromString('<html><body><p>hello</p></body></html>', 'text/html')
console.log(doc.firstChild.nodeName);

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);

Categories