David Obber created GROOVY-9048:
-----------------------------------

             Summary: Replacing a Groovy XML Node causes problems in 
subsequents findAll calls
                 Key: GROOVY-9048
                 URL: https://issues.apache.org/jira/browse/GROOVY-9048
             Project: Groovy
          Issue Type: Bug
          Components: XML Processing
    Affects Versions: 3.x, 2.5.x
         Environment: Windows/JDK 8
            Reporter: David Obber


I use groovy to parse a XML file using XmlParser. Just to avoid the handling of 
namespace prefixes, I used xmlRoot.'**'.findAll() method to find some nodes. 
The sample code shows how it works correctly until I just read the nodes, 
because each item passed to the closure is a Node object. But when I change the 
contents of a node (in this case, just the text of the node), the next call to 
findAll does not iterate on Node objects. For each character I put in the text, 
a String object is passed to the closure. I solved it checking the type with 
instanceof, but it seems to be that this is a bug. 

Am I doing something wrong or it's a bug?


     class XmlParserTest {

    static final String XML_SAMPLE = """
    <ns0:root>
        <ns0:firstParent>
            <ns0:item1>uppercase_me!</ns0:item1>
        </ns0:firstParent>
        <ns0:secondParent>
            <ns0:item2>uppercase_me_too!/ns0:item2>
        </ns0:secondParent>
    </ns0:root>
    """

        static void main(String[] args) {
            def xmlRoot = new XmlParser(false, false).parseText(XML_SAMPLE)

            //******* find item1 and capitalize its text ********
            def nds1 = xmlRoot.'**'.findAll {
                it.name().equals("ns0:item1")
            }

            Node nd1 = nds1[0]

            //This changes the text of the node, but something strange happens 
to the node tree
            nd1.setValue(nd1.value().toString().toUpperCase())

            //The same problem happens using replaceNode() instead of setValue()
            //Node newNode = new Node(nd1.parent(), nd1.name(), 
nd1.value().toString().toUpperCase())
            //nd1.replaceNode(newNode)

            //******* find item2 and capitalize its text ********
            def nds2 = xmlRoot.'**'.findAll {
                //for each character in the string "uppercase me!" a String is 
passed instead of Node
                //As String doesn't have a name method, an exception is raised
                it.name().equals("ns0:item2")

                //using instanceof fixes the problem, at least for this case
                it instanceof Node && it.name().equals("ns0:item2")
            }

            Node nd2 = nds2[0]
            nd2.setValue(nd2.value().toString().toUpperCase())

            assert nd1.value().toString() == 
nd1.value().toString().toUpperCase()
            assert nd2.value().toString() == 
nd2.value().toString().toUpperCase()
        }

    }



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to