0

我正在做一个需要加载 XML 文件的小项目。我在这里找到了一个很好的代码示例,它扩展了 DefaultHandler 并使用自定义 TreeRender 将 XML 格式化为树视图。代码编译并运行(总是一个加号)并为我提供了我正在寻找的起点,但代码中有一点我不明白。

这是我没有得到的代码片段:

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
    }
}

该类声明了一个名为 _base 的 DefaultMutableTreeNode。startElement() 方法实例化一个名为 current 的新 DefaultMutableTreeNode 然后执行

_base.add(current);
_base = current;

我所有的编程知识都告诉我,第二条语句将新对象(当前)分配给 _base “变量”,使第一条语句无用。但是,如果我取出第一条语句,代码将不再正常工作。事实上,如果我删除任何一个声明,它就不再正常工作。要将元素添加到树中,这两个语句都是必需的。

你能解释一下这里发生了什么吗?我只是不明白。

提前致谢,

史蒂夫

4

3 回答 3

3

_base是对对象的引用。当您说 时_base.add(current),您正在调用一个对该对象进行一些更改的方法。当你然后说_base = current;,_base 成为对不同对象的引用。但是第一个对象仍然存在。如果在其他地方有对它的引用,你对它所做的任何更改仍然会影响程序的其余部分。

于 2013-09-04T01:37:18.527 回答
2

这些变量的名字很糟糕,这导致了大部分的混乱。

该字段_base实际上应该被称为类似的东西,currentNode并且在其中创建的新节点startElement应该是类似的东西childNode

这是相同的代码,但使用这些新变量名重写:

currentNode.add(childNode);
currentNode= childNode;

因此,您会看到,当我们在 XML 文件中输入起始元素时,我们会创建一个新节点并将其添加到 XML 树结构的对象表示中。我们刚刚启动的新子元素作为子元素添加到当前节点。然后我们将当前节点的引用更改为指向这个新的子节点。这使新的子节点成为我们的当前节点。

我假设在您未显示的代码中,endElement我们在其中执行反向操作并将树向上移动到 currentNode 的父级。

于 2013-09-04T01:39:52.797 回答
0

你在我脑海中有一段奇怪的代码,但这就是正在发生的事情:

private DefaultMutableTreeNode _base;

充当currentNode类的全局对象。当你打电话时,startElement你正在这样做:

DefaultMutableTreeNode current = new DefaultMutableTreeNode(tagName);
//Create a new TreeNode item based off the tagName

所以你现在有:

  • _base(没有孩子)

现在您要添加_base新创建的节点的子节点

_base.add(current);

Now that this is done you have:

  • _base (no children)
    • current (child)

Finally

_base = current;

Now you have

  • (parent of _base) (the old base)
    • _base / current

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>
于 2013-09-04T01:42:32.037 回答