标题非常明显。如何将org.w3c.dom.Document的实例转换为Scala NodeSeq,以享受它的便利?
干杯
伯尔萨
答案 0 :(得分:12)
def asXml(dom: org.w3c.dom.Node): Node = {
val dom2sax = new DOM2SAX(dom)
val adapter = new NoBindingFactoryAdapter
dom2sax.setContentHandler(adapter)
dom2sax.parse()
return adapter.rootElem
}
答案 1 :(得分:5)
IttayD的答案适用于所有w3c XML - 除了dom4j w3c兼容的xmls。以下适用于所有w3c类型:
def asXml(dom: _root_.org.w3c.dom.Node): Node = {
val source = new DOMSource(dom)
val adapter = new NoBindingFactoryAdapter
val saxResult = new SAXResult(adapter)
val transformerFactory = javax.xml.transform.TransformerFactory.newInstance()
val transformer = transformerFactory.newTransformer()
transformer.transform(source, saxResult)
adapter.rootElem
}
答案 2 :(得分:3)
我将这段代码写回了另一个方向,从Scala节点到Dom4J节点。它显示了在树上递归的基本思想,并且应该很容易适应:
implicit def scalaToDom4j(n : Node) : DElem = {
def inner(n : Node) : Option[DNode] = {
n match {
case e : Elem =>
val elem = DocumentHelper.createElement(e.label)
for(c <- e.child) yield inner(c) collect {
case Some(child) => elem.add(child)
}
Some(elem)
//as Scala's xml is type-aware, text might not actually be a Text node,
//but an Atom of some other type
case t : Atom[_] =>
Some(DocumentHelper.createText(t.data.toString))
case x => None
}
}
//Attempt the conversion. Throw an exception if something has gone badly wrong
//inner returns an Option[DNode], but the expected top-level type is a DElem
// (which is a subclass of DNode)
//so we also validate this.
inner(trim(n)) map (_.asInstanceOf[DElem]) getOrElse (error("xml failed"))
}
答案 3 :(得分:0)
我有与上面的scalaToDom4j(n)函数类似的递归模式匹配代码,仅在Saxon XdmNode到Scala Node方向上: https://github.com/LeifW/MusicPath/blob/master/src/main/scala/org/musicpath/saxon2scala/Saxon2Scala.scala
目前它只生成Text,Element和非命名空间的Attribute节点,但它应该很容易概括/完成。