【发布时间】:2011-04-24 17:49:38
【问题描述】:
标题是不言自明的。如何将 org.w3c.dom.Document 的实例转换为 Scala NodeSeq,以享受它的便利?
干杯
帕萨
【问题讨论】:
标题是不言自明的。如何将 org.w3c.dom.Document 的实例转换为 Scala NodeSeq,以享受它的便利?
干杯
帕萨
【问题讨论】:
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
}
【讨论】:
org.w3c.dom.Document 到scala.xml.NodeSeq 的转换器,但您的代码将org.w3c.dom.Node 作为参数。 — 并且拥有适当的imports 总是会让事情变得容易一些。
scala.xml.parsing.NoBindingFactoryAdapter,但我找不到DOM2SAX,因为没有钱。或者更好的谷歌返回很多结果,所以我不知道哪个是结果。 — 请:在示例代码中完全限定的类名。谢谢
org.apache.xalan.xsltc.trax.DOM2SAX 这不仅意味着必须知道包名。还必须找出它在哪个外部库中。-剩下的一个:如何将org.w3c.dom.Document 转换为org.w3c.dom.Node。
org.w3c.dom.Document 扩展了org.w3c.dom.Node,您可以将Document 传递到此方法中。
IttayD 的答案适用于所有 w3c XML - 除了 dom4j w3c 兼容的 xml。以下适用于所有 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
}
【讨论】:
javax.xml.transform.dom.DOMSource 在 Android API
transformerFactory来自哪里?
implicit 函数,那就更方便了。上面返回的所有对象都是 scala.xml.Node.
我之前写过这段代码,是为了朝另一个方向发展,从 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"))
}
【讨论】:
我有与上面的 scalaToDom4j(n) 函数类似的递归模式匹配代码,只是在 Saxon XdmNode 到 Scala 节点的方向上: https://github.com/LeifW/MusicPath/blob/master/src/main/scala/org/musicpath/saxon2scala/Saxon2Scala.scala
目前它只制作文本、元素和非命名空间属性节点,但应该很容易概括/完成。
【讨论】: