2

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
*/
4

1 に答える 1

1

私はこの問題をしばらく掘り下げていて、まったく同じことを尋ねようとしていました。オーバーロードされた「=」演算子を使用するときに呼び出されるメソッドが 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の 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 として評価されると思います (理由を理解するには、この時点で助けが必要です :-)。

于 2012-01-16T11:56:14.543 に答える