XML文件解析數據結構


最近在解析Android安裝包內經過編譯的二進制XML文件時想在內存中建立起其對應的樹結構。

想了一早晨,思路如下圖。

多叉樹中的每個節點除了有子節點和兄弟節點以外還有一個指針指向父節點,然后根據狀態轉移圖執行相應的代碼就行。

public void main() {
    XmlTagTree tree = new XmlTagTree();
    while (true) {
        // 獲取xml標簽
        Tag tag = getTag();
        if (tag.isStartTag()) {
            tree.addNode(tag, XmlTagTree.STATE_START);
        } else if (tag.isEndTag()){
            tree.addNode(null, XmlTagTree.STATE_END);    
        }        
    }
}

class Tag {
    private Tag parent;
    private Tag child;
    private Tag next;
}

class XmlTagTree {

    public final static int STATE_START = 0;
    public final static int STATE_END = 1;

    private int mCurrentState = STATE_START;
    private Tag mRoot;
    private Tag mCurrent;
    private XmlTreeOperate[][] mOperates;
    private int mSize = 0;

    public XmlTagTree() {
        mOperates = new XmlTreeOperate[2][2];
        mOperates[STATE_START][STATE_START] = new XmlTreeOperate() {
            @Override
            public void operate(Tag chunk, int state) {
                if (mRoot == null) {
                    // 第一次操作,初始化節點
                    mRoot = chunk;
                    mCurrent = chunk;
                } else {
                    // (START, START) -> addChild
                    mCurrent.child = chunk;
                    chunk.parent = mCurrent;
                    mCurrent = chunk;
                    ++mSize;
                }
            }
        };
        mOperates[STATE_START][STATE_END] = new XmlTreeOperate() {
            @Override
            public void operate(Tag chunk, int state) {
                // (START, END) -> none
                // do not do anything
            }
        };
        mOperates[STATE_END][STATE_START] = new XmlTreeOperate() {
            @Override
            public void operate(Tag chunk, int state) {
                // (END, START) -> addSibling
                 mCurrent.next = chunk;
                chunk.parent = mCurrent.parent;
                mCurrent = chunk;
                ++mSize;
            }
        };
        mOperates[STATE_END][STATE_END] = new XmlTreeOperate() {
            @Override
            public void operate(Tag chunk, int state) {
                // (END, END) -> goParent
                mCurrent = mCurrent.parent;
            }
        };
    }

    public void addNode(Tag chunk, int state) {
        if (mRoot == null && state != STATE_START) {
            throw new RuntimeException("first state in XmlTagTree must be STATE_START");
        }
        mOperates[mCurrentState][state].operate(chunk, state);
        mCurrentState = state;
    }

    private interface XmlTreeOperate {
        void operate(Tag chunk, int state);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM