Scala XML \\ копирует атрибут xmlns.Почему и как я могу это остановить?
-
05-07-2019 - |
Вопрос
В 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.
Решение
В вашем входном документе, <innerTag>
имеет логическое пространство имен "http://xyz"
потому что его родитель <outerTag>
элемент имел это пространство имен.Именно так работают пространства имен XML.
Когда вы просите о <innerTag>
элемент сам по себе, Scala копирует объявление пространства имен из родительского <outerTag>
, поскольку пространство имен является логической частью <innerTag>
, даже если это не было прямо указано в первоначальном документе.
Если вы хотите удалить пространство имен, для этого вам придется выполнить некоторую дополнительную обработку.
Другие советы
Используйте именованный параметр и 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>
Боже, я надеюсь, что я что-то упускаю.IT не могу быть таким неловким!
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
Или я слишком избалован Scala, чтобы думать, что это слишком сложно?
Я столкнулся с чем-то вроде аналогичной проблемы при применении преобразований к подузлам документа.Все результирующие узлы имели 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) )}