XmlSlurper: изменение текста в элементе с пространством имен - PullRequest
2 голосов
/ 13 января 2012

Я не понимаю, почему xml."con:cred"."ser:user" = "modified_username" не меняет текст.Может кто-нибудь объяснить это?

input = """
<kuk:acc xmlns:kuk="kuk">
    <con:cred xmlns:con="http://www.bea.com/wli/sb/resources/config">
        <ser:user xmlns:ser="http://www.bea.com/wli/sb/services">username</ser:user>
    </con:cred>
</kuk:acc>
"""

def xml = new XmlSlurper(keepWhitespace:true).parseText(input).declareNamespace(
    ser:"http://www.bea.com/wli/sb/services",
    con:"http://www.bea.com/wli/sb/resources/config")
println xml."con:cred"."ser:user" 

xml."con:cred"."ser:user" = "modified_username" // That doesn't work
println xml."con:cred"."ser:user" 

xml.cred.user = "modified_username" // That works
println xml."con:cred"."ser:user" 

/*
def outputBuilder = new StreamingMarkupBuilder() 
String result = outputBuilder.bind{ mkp.yield xml }
println result
*/

1 Ответ

1 голос
/ 16 января 2012

Я некоторое время копался в этой проблеме и собирался спросить то же самое. Учитывая, что метод, вызываемый при использовании перегруженного оператора '=', это putAt (int, Object), более подробно рассмотрим код GPathResult :

public void putAt(final int index, final Object newValue) {
    final GPathResult result = (GPathResult)getAt(index);

    if (newValue instanceof Closure) {
        result.replaceNode((Closure)newValue);
    } else {
        result.replaceBody(newValue);
    }
}

показывает, что replaceBody должен быть вызван. Как указывает * tim_yates *, replaceBody работает хорошо, поэтому кажется, что вместо него вызывается replaceNode (я не понимаю, почему). Копаясь в NodeChildren's replaceNode , мы можем видеть, что

protected void replaceNode(final Closure newValue) {
    final Iterator iter = iterator();
    while (iter.hasNext()) {
        final NodeChild result = (NodeChild) iter.next();
        result.replaceNode(newValue);
    }
}

замыкание никогда не вызывается, поэтому ничего не делается, когда вызывается replaceNode. Поэтому я думаю, что в replaceNode есть ошибка (она ничего не делает), и при выполнении xml."con:cred"."ser:user" = "modified_username" правая часть выражения оценивается как Closure (мне нужна помощь в этом вопросе, чтобы понять, почему: -).

...