我的代码在Scala.js中,但我认为从JavaScript的角度来看,它的要点应该很容易理解:
def htmlToXHTML(input: String)
(implicit parser: DOMParser, serializer: XMLSerializer): String = {
val doc = parser.parseFromString(input, "text/html")
val body = getElementByXpath("/html/body", doc).singleNodeValue
val bodyXmlString = serializer.serializeToString(body)
val xmldoc = parser.parseFromString(bodyXmlString, "application/xml")
val xmlDocElems: NodeList = xmldoc.getElementsByTagName("*")
xmlDocElems.foreach{
case elem: Element =>
elem.removeAttribute("xmlns")
println(s"Found element $elem with html: ${elem.outerHTML}")
case node => println(s"Warning: found unexpected non-element node: $node.")
}
xmldoc.firstElementChild.innerHTML
}
上面使用了这个,所以包含它是为了完整性(https://stackoverflow.com/a/14284815/3096687):
def getElementByXpath(xpath: String, doc: Document): XPathResult =
doc.evaluate(
xpath, doc, null.asInstanceOf[XPathNSResolver],
XPathResult.FIRST_ORDERED_NODE_TYPE, null
)
简而言之,此函数读取HTML字符串,将其转换为HTML文档,序列化为XML,以XML格式重新分析,并查找文档中的所有元素并在其上循环(foreach
),然后删除xmlns
属性。但是,生成的innerHTML似乎仍然在元素上具有xmlns
属性,即使第一个println
(又名console.log
)表示我们正在查找有问题的元素,但不会删除xmlns
属性。
问题可能来自DTD中指定的default values:
如果在DTD中定义了属性的默认值,则会立即显示一个具有默认值的新属性
答案 0 :(得分:1)
我可能会欺骗并从结果字符串中移除xmlns
,因为它是huge pain以使元素失去其命名空间。
如果你坚持这样做,你可以尝试在走原始DOM的同时从头开始构建文档 - 迂腐地复制除命名空间之外的所有内容(即使用带有空命名空间的createElementNS?)