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);
        }
    }
  • 相关阅读:
    [题解]小B的询问-莫队水题
    [学习笔记]莫队学习笔记[未完待续]
    ffmpeg设置超时时间
    python signal
    pydantic库使用文档
    rtmp及直播流相关资料
    ffmpeg 将视频转换成m3u8视频
    nginx stop失败问题
    linux使用ssh远程登录服务器
    解决Fcitx输入法文字候选无前端问题
  • 原文地址:https://www.cnblogs.com/mmmmar/p/7638650.html
Copyright © 2011-2022 走看看