【发布时间】:2018-06-28 20:01:35
【问题描述】:
我的代码在 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 中定义了属性的默认值,则会立即出现带有默认值的新属性
【问题讨论】:
-
我只是尝试
elem.setAttribute("xmlns", "")而不是remove,但结果很奇怪:<a0:br xmlns:a0="http://www.w3.org/1999/xhtml" xmlns="" />- 我猜它不能很好地处理缺少命名空间的问题。 -
您误解了 DOM API 的工作原理。即使您删除了 xmlns 属性,该元素的限定名称仍包括其名称空间 URI。将 xmlns 属性视为命名空间 URI 的交叉检查,而不是命名空间 URI 本身。
-
@Alohci,谢谢,是的,我想我在某种程度上理解这一点,这最终更多是序列化格式的问题(但
XMLSerializer似乎不可配置,所以我在尝试解决这个问题)
标签: javascript dom scala.js