[
https://issues.apache.org/jira/browse/GROOVY-9048?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
David Obber updated GROOVY-9048:
--------------------------------
Description:
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 xmlns:ns0="mycompany.com"{{}}>
<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()
}
}
was:
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()
}
}
> 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
> Priority: Minor
>
> 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 xmlns:ns0="mycompany.com"{{}}>
> <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)