2010-10-13 111 views

回答

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 
    } 
+0

的問題問一個轉換器從'org.w3c.dom.Document'到'scala.xml.NodeSeq'但你的代碼需要'org.w3c.dom中。節點「作爲參數。 - 而擁有合適的'進口'總能讓它變得容易一些。 – Martin 2011-06-19 07:37:22

+1

我發現'scala.xml.parsing.NoBindingFactoryAdapter',但我找不到'DOM2SAX'沒有錢。或者更好的谷歌返回到許多結果,所以我不知道哪一個。 - 請在示例代碼完全限定的類名稱。謝謝 – Martin 2011-06-19 08:01:19

+0

我想你的意思是'org.apache.xalan.xsltc.trax.DOM2SAX'這不僅意味着必須知道包名。一個也必須找出它在哪個外部庫。 - 所以剩下的一個:如何將org.w3c.dom.Document轉換成org.w3c.dom.Node。 – Martin 2011-06-19 09:07:46

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")) 
} 
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 
    } 
+0

我說的和IttayD一樣:請在示例代碼中使用完全限定的類名。謝謝。而且糟糕的是'javax.xml.transform.dom.DOMSource'在Android API <8上不可用。但我想這不是你的問題。 – Martin 2011-06-19 08:06:21

+0

你的'transformerFactory'從哪裏來? – 2011-08-05 14:04:21

+1

@ Jean-Philippe Pellet在包含對象中定義了一個val transformerFactory = javax.xml.transform.TransformerFactory.newInstance()。 – 2011-08-18 05:19:07