You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "David Obber (JIRA)" <ji...@apache.org> on 2019/03/21 13:32:00 UTC

[jira] [Created] (GROOVY-9048) Replacing a Groovy XML Node causes problems in subsequents findAll calls

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)