Scala XML \\ копирует атрибут xmlns. Почему и как я могу это остановить? - PullRequest
2 голосов
/ 21 октября 2009

В Scala REPL:

val input = <outerTag xmlns="http://xyz"> <innerTag> </innerTag> </outerTag>

input\\@"innerTag"

=>

<innerTag xmlns="http://xyz"> </innerTag>

Как мне остановить Scala? Почему он не может просто дать мне <innerTag> </innerTag>? Как я могу остановить это (или просто удалить атрибуты xmlns)?

Спасибо!

Джо

Разъяснение: Моя общая задача - разбить XML-файл и объединить его. Таким образом, этот узел будет извлечен из-под корневого узла (который имеет атрибут xmlns), а затем интегрирован обратно в документ под корнем, который снова содержит xmlns.

Ответы [ 4 ]

3 голосов
/ 21 октября 2009

Используйте именованный параметр и Elem.copy () в Scala 2.8.0:

scala> import scala.xml._
import scala.xml._

scala> val outer = <outerTag xmlns="http://xyz"><innerTag></innerTag></outerTag>
outer: scala.xml.Elem = <outerTag xmlns="http://xyz"><innerTag></innerTag></outerTag>

scala> outer \\ "innerTag" map { case e: Elem => e.copy(scope = TopScope) }
res0: scala.xml.NodeSeq = <innerTag></innerTag>
3 голосов
/ 21 октября 2009

Во входном документе <innerTag> имеет логическое пространство имен "http://xyz", поскольку его родительский элемент <outerTag> имел это пространство имен. Так работают пространства имен XML.

Когда вы запрашиваете элемент <innerTag> самостоятельно, Scala копирует объявление пространства имен из родительского <outerTag>, потому что пространство имен является логической частью <innerTag>, даже если оно не было явно указано в исходный документ.

Если вы хотите удалить пространство имен, вам придется выполнить дополнительную обработку, чтобы сделать это.

1 голос
/ 28 июля 2010

Я столкнулся с некой подобной проблемой при применении преобразований к подузлам документа. Все получившиеся узлы имели xmlns на узлах.

После завершения преобразования я использовал следующую функцию, чтобы «очистить» документ для целей печати. ​​

def transformForPrinting(doc : Elem) : Elem = { 
 def stripNamespaces(node : Node) : Node = {
     node match {
         case e : Elem => 
             e.copy(scope = TopScope, child = e.child map (stripNamespaces))
         case _ => node;
     }
 }
 doc.copy( child = doc.child map (stripNamespaces) )}
1 голос
/ 21 октября 2009

Боже, я надеюсь, что что-то упустил. Это не может быть таким неловким!

import scala.xml._
import scala.xml.tranform._

val rw = new RewriteRule { 
  override def transform(n: Node) = n match {
    case Elem(p, l, a, s, children@ _*) => Elem(p, l, a, TopScope, children: _*)
    case x => x
  }
  override def transform(ns: Seq[Node]): Seq[Node] = ns flatMap transform
}
val rt = new RuleTransformer(rw)

val input = <outerTag xmlns="http://xyz"> <innerTag> </innerTag> </outerTag>

val result = input \\ "innerTag" map rt

Или я слишком избалован Скалой, чтобы думать, что это слишком сложно?

...