2010-10-13 3 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. Node'. - И наличие соответствующего «импорта» всегда делает это немного легче. – Martin

+1

Я нашел 'scala.xml.parsing.NoBindingFactoryAdapter', но я не могу найти' DOM2SAX' за меньшие деньги. Или лучше google возвращает много результатов, поэтому я не знаю, что это такое. - Просьба: В качестве примера введите полные имена классов. Спасибо – Martin

+0

Я предполагаю, что вы имели в виду 'org.apache.xalan.xsltc.trax.DOM2SAX', который не только означает, что нужно знать имя пакета. Также нужно выяснить, в какую внешнюю библиотеку он находится. - Итак, один из них: Как преобразовать 'org.w3c.dom.Document' в' org.w3c.dom.Node'. – Martin

3

Я написал этот код, некоторое время назад, чтобы идти в другом направлении, от узла к Scala DOM4J Node. Это показывает основную идею рекурсии по дереву и должно быть достаточно легко адаптироваться:

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

У меня есть рекурсивная модель сопоставление код похож на scalaToDom4j (п) функция выше, только в саксонской XdmNode to Scala Node direction up at: https://github.com/LeifW/MusicPath/blob/master/src/main/scala/org/musicpath/saxon2scala/Saxon2Scala.scala

В настоящее время он просто создает узлы атрибутов Text, Element и non-namespaced, но его должно быть легко обобщать/заканчивать.

5

Ответ IttayD хорош для всех XML-файлов w3c - кроме 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

+0

Откуда берет ваш 'transformerFactory'? –

+1

@ Jean-Philippe Pellet есть трансформатор valFactory = javax.xml.transform.TransformerFactory.newInstance(), определенный в содержащем объекте. –