使用Sax Parser解析xml时的父/子关系

时间:2015-01-03 20:35:00

标签: java android saxparser

我已经看到了这个问题,但没有回答,我希望这次我很幸运。正如问题所述,我试图用SAX Parser解析xml并需要维护父/子关系。由于SAX Parser没有上下文,所以我需要创建一些自己的上下文。我已经过了一半但仍坚持到这一步。下面是我的xml的示例结构,

<Folder name="Folder1" nodeId="1">
<Level1 name="NodeA1" nodeId="2">
    <Level2 name="NodeA11" ImageId="Image11.png" nodeId="2" />
    <Level2 name="NodeA12" ImageId="Image12.png" nodeId="2" />    
</Level1>
<Level1 name="NodeA2" nodeId="3">
    <Level2 name="SubNodeA2" nodeId="131">
        <Level3 name="NodeA21" ImageId="Image21.png" nodeId="131" />  
    </Level2>
    <Level2 name="NodeA13" ImageId="Image13.png" nodeId="3" />
    <Level2 name="NodeA14" ImageId="Image14.png" nodeId="3" />
</Level1>
</Folder>
<Folder name="Folder2" nodeId="2">
<Level1 name="NodeB1" nodeId="2">
    <Level2 name="Node1B1" ImageId="Image11.png" nodeId="2" />
    <Level2 name="Node1B2" ImageId="Image12.png" nodeId="2" />    
</Level1>
<Level1 name="NodeB2" nodeId="3">
    <Level2 name="SubNodeB2" nodeId="131">
        <Level3 name="NodeB21" ImageId="Image21.png" nodeId="131" />  
    </Level2>
    <Level2 name="NodeB13" ImageId="Image13.png" nodeId="3" />
    <Level2 name="NodeB14" ImageId="Image14.png" nodeId="3" />
</Level1>

用于存储xml结构的属性类

private String nodeName;
private String name;
private String ImageId;
private int nodeId;
private String folderName;

在Default处理程序中,以下startElement代码用于处理节点和属性,

public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

        ListItems_Nodes node= new ListItems_Nodes();

        if (qName.equalsIgnoreCase("Folder")) {
            FolderName = attributes.getValue("name").toString();
        }

        nextLevelNode.setFolderName(FolderName);
        nextLevelNode.setNodeName(qName);
        nextLevelNode.setName(attributes.getValue("name").toString();
        nextLevelNode.setChartId(attributes.getValue("ImageId").toString());
        nextLevelNode.setNodeId(Integer.parseInt(attributes.getValue("nodeId")));

        NodeLevelValues.add(nextLevelNode);
}

我可以使用任何文件夹的ImageId访问节点,因为它们与父节点具有相同的nodeId,但如果节点的子节点不是Image,则其nodeId与父节点不同,我无法访问特定的子节点。现在在startElement里面我想用每个节点Id存储父名。我已经为Folder节点实现了它,它工作正常,但对于其他节点,如Level1,Level2 .... Level(n)我无法找到实现它的方法。

任何帮助都将受到高度赞赏。感谢

1 个答案:

答案 0 :(得分:0)

似乎没有人有兴趣回答这个问题。我发现这不是一个愚蠢的问题,可能没有人知道如何解决这个问题。我找到了关于文档订单索引的非常翔实和有趣的文章,这篇文章解决了我的父/子关系问题。这不仅解决了我的问题,而且由于这一点,我的100多行代码(检查/条件)现在缩短为只有6到7行代码。该文章可在http://www.ibm.com/developerworks/library/x-tipsaxdo2/找到。

我将简要介绍它在我的应用程序中的变化。引入了两个全局变量,

private int m_nodeIx;
private Stack<Integer> m_parentStack;

还在我的属性类中添加了两个字段

private int nodeIndex;
private int parentIndex;

为我的DefaultHandler添加了startDocument方法,

public void startDocument() throws SAXException {
    m_nodeIx = -1;
    m_parentStack = new Stack<Integer>();
    m_parentStack.push(Integer.valueOf(m_nodeIx));
}

在startElement中,

++ m_nodeIx;
int parentNodeIx = ((Integer) m_parentStack.peek()).intValue();

在填充所有属性字段的末尾,

propertyClass.setNodeIndex(m_nodeIx);
propertyClass.setParentIndex(parentNodeIx);
m_parentStack.push(Integer.valueOf( m_nodeIx ));

最后在我的endElement中,

m_parentStack.pop();

因此,如果任何机构想要具有相同的功能,他们可以很容易地理解这里正在做什么。 (1)现在为每个节点分配一个索引。 (2)每个子节点的父索引等于父节点的节点索引。我希望这对任何人都有用。 (失望但很乐意自己解决)