Scala xml copia o atributo xmlns. Por que e como posso parar?
-
05-07-2019 - |
Pergunta
Em Scala Repl:
val input = <outerTag xmlns="http://xyz"> <innerTag> </innerTag> </outerTag>
input\\@"innerTag"
=>
<innerTag xmlns="http://xyz"> </innerTag>
Como faço para parar o scala fazer isso? Por que não pode simplesmente me dar <innerTag> </innerTag>
? Como posso impedir que isso aconteça (ou remover o xmlns
atributos simplesmente)?
Obrigado!
Joe
Esclarecimento: Minha tarefa geral é cortar um arquivo XML e recombiná -lo. Portanto, esse nó será retirado de baixo do nó raiz (que possui o atributo XMLNS) e depois integrado de volta a um documento sob uma raiz que novamente possui os XMLNs.
Solução
Em seu documento de entrada, <innerTag>
tem o espaço para nome lógico "http://xyz"
Porque seu pai <outerTag>
O elemento tinha esse espaço para nome. É assim que os namespaces XML funcionam.
Quando você pede o <innerTag>
Elemento por si só, Scala copia a declaração de namespace do pai <outerTag>
, porque o espaço para nome é uma parte lógica do <innerTag>
, mesmo que não tenha sido explicitamente declarado no documento inicial.
Se você deseja remover o espaço para nome, precisará executar algum processamento adicional para fazê -lo.
Outras dicas
Use o parâmetro nomeado e elem.copy () em 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>
Deus, espero estar perdendo alguma coisa. Isto não pode Seja tão estranho!
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
Ou sou muito estragado com Scala para pensar que isso é excessivamente complexo?
Eu encontrei uma espécie de problema semelhante ao aplicar transformações em sub-nodos de um documento. Todos os nós resultantes tinham os XMLNs nos nós.
Depois de concluir a transformação, usei a seguinte função para 'limpar' o documento para fins de impressão.
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) )}