Scala:将org.w3c.dom.Document转换为scala.xml.NodeSeq

时间:2022-10-30 13:54:18

Title is pretty self-explanatory. How can I convert an instance of org.w3c.dom.Document to a Scala NodeSeq, to enjoy it's facilitation?

标题非常明显。如何将org.w3c.dom.Document的实例转换为Scala NodeSeq,以享受它的便利?

Cheers
Parsa

干杯帕萨

4 个解决方案

#1


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
  }

#2


5  

IttayD's answer is good for all w3c XMLs - except dom4j w3c compatible xmls. the following works for all w3c types:

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
  }

#3


3  

I wrote this code a while back to go in the other direction, from a Scala node to a Dom4J Node. It shows the basic idea of recursing over a tree and should be easy enough to adapt:

我将这段代码写回了另一个方向,从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"))
}

#4


0  

I have recursive pattern-matching code similiar to the scalaToDom4j(n) function above, only in the Saxon XdmNode to Scala Node direction up at: https://github.com/LeifW/MusicPath/blob/master/src/main/scala/org/musicpath/saxon2scala/Saxon2Scala.scala

我有上面的scalaToDom4j(n)函数类似的递归模式匹配代码,仅在Saxon XdmNode到Scala Node方向上:https://github.com/LeifW/MusicPath/blob/master/src/main/scala /org/musicpath/saxon2scala/Saxon2Scala.scala

Currently it just makes Text, Element, and non-namespaced Attribute nodes, but it should be easy to generalize / finish.

目前它只生成Text,Element和非命名空间的Attribute节点,但它应该很容易概括/完成。

#1


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
  }

#2


5  

IttayD's answer is good for all w3c XMLs - except dom4j w3c compatible xmls. the following works for all w3c types:

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
  }

#3


3  

I wrote this code a while back to go in the other direction, from a Scala node to a Dom4J Node. It shows the basic idea of recursing over a tree and should be easy enough to adapt:

我将这段代码写回了另一个方向,从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"))
}

#4


0  

I have recursive pattern-matching code similiar to the scalaToDom4j(n) function above, only in the Saxon XdmNode to Scala Node direction up at: https://github.com/LeifW/MusicPath/blob/master/src/main/scala/org/musicpath/saxon2scala/Saxon2Scala.scala

我有上面的scalaToDom4j(n)函数类似的递归模式匹配代码,仅在Saxon XdmNode到Scala Node方向上:https://github.com/LeifW/MusicPath/blob/master/src/main/scala /org/musicpath/saxon2scala/Saxon2Scala.scala

Currently it just makes Text, Element, and non-namespaced Attribute nodes, but it should be easy to generalize / finish.

目前它只生成Text,Element和非命名空间的Attribute节点,但它应该很容易概括/完成。