npm library xmldom doesn’t have something like innerHTML
. It has only specific features, not full features of W3C DOM. Here, I introduce how to change inner html text with xmldom.
Environment
- NodeJS 10.9.0
- npm 6.6.0
- xmldom 0.1.27
- Kotlin 1.3.11
How to do
Now, suppose change the internal html of one tag, which is gotten by getElementById
or something else. I’ll show the example code first, in Kotlin. Compile it to JavaScript, then it works.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
import org.w3c.dom.* import org.w3c.dom.parsing.DOMParser fun main() { val html = """ <!DOCTYPE html> <html> <head></head> <body> <header data-sample="sample"> </header> </body> </html> """.trimIndent() val doc = DOMParser().parseFromString( html, "text/html" ) val tag = doc.getElementsByTagName("header")[0]!! val innerHtml = "<p>Hello World!</p>" val parentNode = tag.parentNode!! val attributes = tag.attributes val tagName = tag.tagName.toLowerCase() var openText = "<$tagName" for (i in 0 until attributes.length) openText += " ${attributes[i]!!.name}=" + ""${attributes[i]!!.value}"" openText += ">" val closeText = "</$tagName>" val newElementText = openText + innerHtml + closeText parentNode.replaceChild( DOMParser().parseFromString( newElementText, "text/html" ), tag ) println( doc.toString().replace( " xmlns="http://www.w3.org/1999/xhtml"", "" ) ) } |
It uses replaceChild
to change internal HTML. At the last, I remove xmlns="http://www.w3.org/1999/xhtml"
from entire html string, because the HTML output from toString
method contains the attribute and value.
In my environment, the code is compiled to app.js
, and NodeJS code is as follows.
1 2 3 4 |
global.DOMParser = require('xmldom').DOMParser global.kotlin = require("path/out/production/app/lib/kotlin.js") require("path/out/production/app/app.js") |
Executing the script, the following message is output.
1 2 3 4 5 6 7 |
<!DOCTYPE html> <html> <head></head> <body> <header data-sample="sample"><p>Hello World!</p></header> </body> </html> |
Split to function
To make it more useful, extract changing inner html part to the function. Below I created the function, changeInnerHtml
, for replacing the innerHTML
value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
import org.w3c.dom.* import org.w3c.dom.parsing.DOMParser fun changeInnerHtml(tag: Element, innerHtml: String) { val parentNode = tag.parentNode!! val attributes = tag.attributes val tagName = tag.tagName.toLowerCase() var openText = "<$tagName" for (i in 0 until attributes.length) openText += " ${attributes[i]!!.name}=" + ""${attributes[i]!!.value}"" openText += ">" val closeText = "</$tagName>" parentNode.replaceChild( DOMParser().parseFromString( openText + innerHtml + closeText, "text/html" ), tag ) } fun main() { val html = """ <!DOCTYPE html> <html> <head></head> <body> <header data-sample="sample"> </header> </body> </html> """.trimIndent() val doc = DOMParser().parseFromString( html, "text/html" ) val tag = doc.getElementsByTagName("header")[0]!! val innerHtml = "<p>Hello World!</p>" changeInnerHtml(tag, innerHtml) println( doc.toString().replace( " xmlns="http://www.w3.org/1999/xhtml"", "" ) ) } |