Groovy XML и пространство имен "xml:" - PullRequest
7 голосов
/ 06 марта 2012

Я пишу несколько сценариев для модификации XML-файлов.В рассматриваемых файлах используется элемент xml: lang.Groovy (XmlSlurper), похоже, вставляет пространство имен tag0, что, я бы не возражал, слишком сильно, за исключением того, что оно прерывает последующую обработку с помощью XmlUtil.

Пример:

import groovy.xml.StreamingMarkupBuilder
import groovy.xml.XmlUtil

String source = """<?xml version='1.0' encoding='UTF-8'?>
<root>
    <one xml:lang="en">First</one>
    <one xml:lang="de">Second</one>
</root>
"""

def root = new XmlSlurper().parseText(source).declareNamespace(xml: "http://www.w3.org/XML/1998/namespace")
println root
String xml = new StreamingMarkupBuilder().bind{ 
    mkp.xmlDeclaration() 
    out << root 
}
println xml
println XmlUtil.serialize(xml)

результатыin

[Fatal Error] :2:44: The value of the attribute "prefix="xmlns",localpart="tag0",rawname="xmlns:tag0"" is invalid. Prefixed namespace bindings may not be empty.

Предполагается, что пространство имен xml: существует по умолчанию, и я попытался добавить его с помощью .declareNamespace (), но, похоже, это не помогло.Я чувствую, что упускаю что-то очевидное, но Google не смог сказать мне, что это такое.

Ответы [ 2 ]

8 голосов
/ 06 марта 2012

Найдено этой ветки от нескольких лет назад, где говорится:

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

SMB обычно не использует пространство имен по умолчанию, поэтому изобретает тег и использует его для явной маркировки каждого элемента в пространстве имен. Что касается синтаксического анализатора XML, не имеет значения, как обозначается пространство имен. Однако существуют косметические причины, по которым иногда желательно использовать пространства имен по умолчанию.

Если вы поставите mkp.declareNamespace("": "http://java.sun.com/xml/ns/j2ee") в качестве первой строки в закрытии вашего строителя, вы должны получить желаемый результат.

Однако, похоже, это не работает

Единственное решение, которое я нашел, - заставить Slurper игнорировать пространства имен и проверки;

def root = new XmlSlurper(false,false).parseText(source)
2 голосов
/ 26 января 2014

Установка пространства имен по умолчанию для пустого тега работает для меня (без добавления tag0). Я использую конструктор XmlSlurper по умолчанию, чтобы иметь рабочее пространство имен и проверку, например:

def root = new XmlSlurper().parseText(source).declareNamespace(xml: "http://www.w3.org/XML/1998/namespace")

При связывании объявлять пустое пространство имен:

def writer = new StreamingMarkupBuilder().bind {
    mkp.declareNamespace("": "") //get rid of "tag0"
    mkp.declareNamespace(xml: "http://www.w3.org/XML/1998/namespace") 
    mkp.yield root
}
...