zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    .Net 4.5中的HttpClient试用
    在silverlight中使用微软地图
    SQL语句之语法汇总(一)
    如何将google地图中的经纬度值导入ArcMap
    毕业周年季
    SQL语句之语法汇总(二)
    定时出现和消失的层
    实现iFrame自适应高度,原来很简单!
    .Net 中的反射(查看基本类型信息) Part.2
    反射一些文章
  • 原文地址:https://www.cnblogs.com/mmmmar/p/7638650.html
Copyright © 2011-2022 走看看