Il titolo è piuttosto auto-esplicativo. Come posso convertire un'istanza di org.w3c.dom.Document in Scala NodeSeq, per goderne la facilitazione?Scala: Converti org.w3c.dom.Document in scala.xml.NodeSeq
Acclamazioni
Parsa
Il titolo è piuttosto auto-esplicativo. Come posso convertire un'istanza di org.w3c.dom.Document in Scala NodeSeq, per goderne la facilitazione?Scala: Converti org.w3c.dom.Document in scala.xml.NodeSeq
Acclamazioni
Parsa
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
}
Ho scritto questo codice un po 'indietro per andare nella direzione opposta, da un nodo a un nodo Scala DOM4J. Essa mostra l'idea di base di recursing su un albero e dovrebbe essere abbastanza facile da adattare:
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"))
}
devo ricorsiva codice di pattern-matching simile al scalaToDom4j (n) di cui sopra, solo nel Saxon XdmNode direzione Scala Nodo fino a: https://github.com/LeifW/MusicPath/blob/master/src/main/scala/org/musicpath/saxon2scala/Saxon2Scala.scala
Attualmente crea solo nodi di attributo Testo, Elemento e non assegnato a un nome, ma dovrebbe essere facile da generalizzare/finire.
La risposta di IttayD è valida per tutti gli XML di w3c, ad eccezione degli xml compatibili con dom4j w3c. le seguenti opere per ogni tipo 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
}
Dico lo stesso di IttayD: Per favore: nel codice di esempio nomi di classi completamente qualificati. Grazie. E a male che 'javax.xml.transform.dom.DOMSource' non è disponibile su Android API <8. Ma immagino che non sia il tuo problema. – Martin
Da dove proviene il tuo 'transformerFactory'? –
@ Jean-Philippe Pellet c'è un val transformerFactory = javax.xml.transform.TransformerFactory.newInstance() definito nell'oggetto contenitore. –
Le domande chiedono un convertitore da 'org.w3c.dom.Document' a' scala.xml.NodeSeq' ma il vostro codice di prendere un 'org.w3c.dom. Nodo' come parametro. - E avere "importazioni" appropriate semplifica sempre la procedura. – Martin
Ho trovato 'scala.xml.parsing.NoBindingFactoryAdapter' ma non riesco a trovare' DOM2SAX' per meno soldi. O meglio google ritorna a molti risultati quindi non so quale sia quello. - Per favore: nel codice di esempio nomi di classi completi. Grazie – Martin
Suppongo che tu intenda "org.apache.xalan.xsltc.trax.DOM2SAX' che non significa solo che uno deve conoscere il nome del pacchetto. Si deve anche scoprire in quale libreria esterna si trova. - Quindi uno a sinistra: come convertire un 'org.w.c.dom.documento' in un 'org.w3c.dom.Node'. – Martin