標題非常明瞭。如何將org.w3c.dom.Document的實例轉換爲Scala NodeSeq,以享受它的便利?Scala:將org.w3c.dom.Document轉換爲scala.xml.NodeSeq
乾杯
帕爾薩
標題非常明瞭。如何將org.w3c.dom.Document的實例轉換爲Scala NodeSeq,以享受它的便利?Scala:將org.w3c.dom.Document轉換爲scala.xml.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
}
我寫了這個代碼前陣子在另一個方向走,從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)的上述功能,只有在薩克森XdmNode到Scala節點方向: https://github.com/LeifW/MusicPath/blob/master/src/main/scala/org/musicpath/saxon2scala/Saxon2Scala.scala
目前它只是使文本,元素和非名稱空間屬性節點,但它應該很容易推廣/完成。
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
}
我說的和IttayD一樣:請在示例代碼中使用完全限定的類名。謝謝。而且糟糕的是'javax.xml.transform.dom.DOMSource'在Android API <8上不可用。但我想這不是你的問題。 – Martin 2011-06-19 08:06:21
你的'transformerFactory'從哪裏來? – 2011-08-05 14:04:21
@ Jean-Philippe Pellet在包含對象中定義了一個val transformerFactory = javax.xml.transform.TransformerFactory.newInstance()。 – 2011-08-18 05:19:07
的問題問一個轉換器從'org.w3c.dom.Document'到'scala.xml.NodeSeq'但你的代碼需要'org.w3c.dom中。節點「作爲參數。 - 而擁有合適的'進口'總能讓它變得容易一些。 – Martin 2011-06-19 07:37:22
我發現'scala.xml.parsing.NoBindingFactoryAdapter',但我找不到'DOM2SAX'沒有錢。或者更好的谷歌返回到許多結果,所以我不知道哪一個。 - 請在示例代碼完全限定的類名稱。謝謝 – Martin 2011-06-19 08:01:19
我想你的意思是'org.apache.xalan.xsltc.trax.DOM2SAX'這不僅意味着必須知道包名。一個也必須找出它在哪個外部庫。 - 所以剩下的一個:如何將org.w3c.dom.Document轉換成org.w3c.dom.Node。 – Martin 2011-06-19 09:07:46