XmlSlurper:使用命名空间更改元素中的文本

时间:2012-01-13 10:05:15

标签: groovy xmlslurper

我不明白为什么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 个答案:

答案 0 :(得分:1)

我一直在挖掘这个问题,并且正要问同样的问题。鉴于使用重载'='运算符时调用的方法是putAt(int,Object),仔细研究GPathResult code

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(我需要帮助才能理解为什么: - )。