Tiêu đề khá dễ hiểu. Làm thế nào tôi có thể chuyển đổi một thể hiện của org.w3c.dom.Document thành Scala NodeSeq, để tận hưởng sự thuận lợi của nó?Scala: Chuyển đổi org.w3c.dom.Document thành scala.xml.NodeSeq
Cheers
Parsa
Tiêu đề khá dễ hiểu. Làm thế nào tôi có thể chuyển đổi một thể hiện của org.w3c.dom.Document thành Scala NodeSeq, để tận hưởng sự thuận lợi của nó?Scala: Chuyển đổi org.w3c.dom.Document thành scala.xml.NodeSeq
Cheers
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
}
tôi đã viết mã này một khi trở lại đi theo một hướng khác, từ một nút Scala đến một Dom4J Node. Nó cho thấy ý tưởng cơ bản của recursing trên một cây và nên được dễ dàng, đủ để thích nghi:
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"))
}
Tôi có đệ quy đang mô hình khớp tương tự như các scalaToDom4j (n) chức năng trên, chỉ trong Saxon XdmNode đến Hướng dẫn của Scala Node tại: https://github.com/LeifW/MusicPath/blob/master/src/main/scala/org/musicpath/saxon2scala/Saxon2Scala.scala
Hiện tại, nó chỉ làm cho nút Thuộc tính văn bản, Thành phần và không có tên, nhưng sẽ dễ dàng khái quát/hoàn thành.
Câu trả lời của IttayD là tốt cho tất cả các XML của W3C - ngoại trừ các xml tương thích với dom4j w3c. các công trình sau đây hoạt động cho tất cả các loại 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
}
Tôi nói giống với IttayD: Xin vui lòng: Trong ví dụ mã tên đầy đủ các tên lớp. Cảm ơn. Và xấu rằng 'javax.xml.transform.dom.DOMSource' không có sẵn trên Android API <8. Nhưng tôi đoán đó không phải là vấn đề của bạn. – Martin
Trường hợp của bạn 'transformerFactory' đến từ đâu? –
@ Jean-Philippe Pellet có biến áp valFactory = javax.xml.transform.TransformerFactory.newInstance() được định nghĩa trong đối tượng chứa. –
Các câu hỏi yêu cầu trình chuyển đổi từ 'org.w3c.dom.Document' thành' scala.xml.NodeSeq' nhưng mã của bạn có 'org.w3c.dom. Node' làm tham số. - Và việc có 'hàng nhập khẩu phù hợp 'luôn làm cho việc này dễ dàng hơn một chút. – Martin
Tôi đã tìm thấy 'scala.xml.parsing.NoBindingFactoryAdapter' nhưng tôi không thể tìm thấy' DOM2SAX' cho ít tiền hơn. Hoặc tốt hơn google trở lại nhiều kết quả vì vậy tôi không biết đó là một. - Vui lòng: Trong ví dụ mã, tên lớp đủ điều kiện. Cảm ơn – Martin
Tôi đoán bạn có nghĩa là 'org.apache.xalan.xsltc.trax.DOM2SAX' không chỉ có nghĩa là người ta phải biết tên gói. Người ta cũng phải tìm ra thư viện bên ngoài nào. - Vì vậy, một bên trái: Cách chuyển đổi một 'org.w3c.dom.Document' thành' org.w3c.dom.Node'. – Martin