Reputation: 3
I am working on a small project that requires loading an XML file. I found a nice code sample that extends DefaultHandler and uses a custom TreeRender to format the XML into a treeview here. The code compiles and runs (always a plus) and gives me the starting point I'm looking for but there is one little thing I don't understand in the code.
Here's the code snippet that I don't get:
public class XmlTreeView extends DefaultHandler {
private DefaultMutableTreeNode _base;
<snip>
@Override
public void startElement(String uri, String localName, String tagName, Attributes attr) throws SAXException {
System.out.println("startElement: uri=" + uri + " localname=" + localName + " tagName=" + tagName );
DefaultMutableTreeNode current = new DefaultMutableTreeNode(tagName);
_base.add(current);
_base = current;
for (int i = 0; i < attr.getLength(); i++) {
// <snip> attribute processing
}
}
The class declares a DefaultMutableTreeNode named _base. The startElement() method instantiates a new DefaultMutableTreeNode named current then does
_base.add(current);
_base = current;
All my programming knowledge tells me that the second statement assigns the new object (current) to the _base "variable", making the first statement useless. However, if I take out the first statement the code no longer works properly. In fact, if I take out either statement it no longer works properly. Both statements are required for the element to get added to the tree.
Can you explain to me what's happening here? I just don't get it.
Thanks in advance,
Steve
Upvotes: 0
Views: 93
Reputation: 1621
You have a strange piece of code here in my mind but this is what is happening:
private DefaultMutableTreeNode _base;
Is acting as a global currentNode
for the class. When you call startElement
you are doing this:
DefaultMutableTreeNode current = new DefaultMutableTreeNode(tagName);
//Create a new TreeNode item based off the tagName
So you now have:
Now you are going to add to the children of _base
, the freshly created node
_base.add(current);
Now that this is done you have:
Finally
_base = current;
Now you have
The reference to _base
now points to the freshly created child. When you call endElement
, you will exit out of the _base
and return to your old _base
_base
is storing the xmlElement that you are currently working on. When you call startElement
all calls to setAttribute
or startElement
will be based off this.
SUMMARY:
Here is what this looks like played out in code:
XmlWriter xWriter;
xWriter.startElement("NPC"); //_base becomes new node "hello"
xWriter.startAttribute("Greeting", "Hi"); //attribute is now set to _base (or greeting)
xWriter.startElement("Data"); //_base becomes new node "data"
xWriter.startAttribute("Height", "200"); //attribute is now set to _base (or data)
xWriter.endElement(); //on end element you move to parent of data, so greeting
xWriter.endElement(); //again you move to the parent
Creating:
<NPC Greeting='Hi'>
<Data Height='200'/>
</NPC>
Upvotes: 0
Reputation: 31648
These variables are badly named which is causing most of the confusion.
The field _base
should really be called something like currentNode
and the new Node created in startElement
should be something like childNode
.
Here is the same code but rewritten using these new variable names:
currentNode.add(childNode);
currentNode= childNode;
So you see when we enter a start element in the XML file, we create a new node and add it to our Object representation of the tree structure of the XML. The new child element that we just started is added to the current node as a child. Then we change our reference of the current node to point to this new child node. This makes the new child node our current node.
I assume in code that you haven't shown, there is an endElement
where we do the reverse operation and move up the tree to the currentNode's parent.
Upvotes: 2
Reputation: 31689
_base
is a reference to an object. When you say _base.add(current)
, you are calling a method that makes some change to that object. When you then say _base = current;
, _base
becomes a reference to a different object. But the first object is still there. And whatever change you made to it can still impact the rest of the program, if there's a reference to it somewhere else.
Upvotes: 3