I have the following response returned from a server. It’s a html fragment.
I want to parse it with DOMParser like this:
let responseText = '<div>Text Content</div><tr><td>Cell</td></tr>';
let doc = new DOMParser().parseFromString(`<body><template>${responseText}</template></body>`, 'text/html');
let fragment = doc.body.firstChild.content;
Here the fragment
variable in runtime contains the following DOM:
#document-fragment
<div>Text Content</div>
Cell
My question: I expected it to contain <tr>
but it doesn’t. How do I change the parsing code so that it properly contains element?
I’m not allowed to change response text.
2
The <tr>
element is only a valid child of <table>
, <thead>
, <tbody>
or <tfoot>
. See excerpt from MDN below for more informaition.
Try wrapping the <tr>
in a <table>
and using createContextualFragment
instead.
let responseText = '<div>Text Content</div><tr><td>Cell</td></tr>';
responseText = responseText
.replace(/<tr>/, '<table>$0')
.replace(/</tr>/, '$0</table>');
const fragment = document.createRange().createContextualFragment(responseText);
const cellContent = fragment.querySelector('td').innerText;
console.log(cellContent); // Cell
.as-console-wrapper { top: 0; max-height: 100% !important; }
See:
MDN ~
<tr>
: The Table Row element ~ Technial summaryPermitted parents
<table>
(only if the table has no child<tbody>
element, and even then only after any<caption>
,<colgroup>
, and<thead>
elements); otherwise, the parent must be<thead>
,<tbody>
or<tfoot>
DomParser is quite strict when parsing HTML. The HTML example you provided is not in accordance with the specification
Here are rules to be followed.
HTML Standard
According to that document, you should not put <div>
next to <tr>
This answer should also help
Create new DOM element