自定义解析器【一】

像xml,html这些标记行语言,我们通常会去采用java自带的解析工具去解析,如果我们要自己写一个类似于pull解析器或者dom解析器,能实现吗?这当然是很麻烦的,但是我们这里可以写一个稍微简单些的解析器。
比如我们要解析的文本是:

<xxml>
<span>
<button id="btn1" width="40" height="40"/>
<label id="label1" width="30" height="40"/> 
</xxml>

这只是一段简单的例子,我们现在的需求是要解析出span,button,label这三个标签,收集每个标签里面的属性,并在控制台打印出来。
我们这里不会用到java自带的xml解析器。而是重新去写一个简单的解析器 。
这里的思路是这样的:
在循环里不停去读字符流的字符,直到遇到结尾为止。
解析到”<”表明是标签控件开始。
如果解析到“/”表示是标签结尾。
打印处理标签内属性
如果是标签内的属性的话,就要把属性加入到当前标签里面。
关键代码如下:

public class Parser {

    int pos  = 0;
    public static final char EOF = (char) -1;
    private Reader reader ;

    public Parser(String parser) {
        this.reader = new StringReader(parser);
    }

    public void parse() throws Exception {

        while (true) {
            char ch = this.getChar();
            if (ch == EOF)
                break;
            else if (ch == '<') {

            } else if (ch == '/') {
                this.ungetChar(2);
                this.parseEndTag(pos);
                System.out.println(ch + " ---- ");
                break;
            } else {

                this.ungetChar(1);
                this.parseText(pos);
            }
        }
        return;
    }   

这里我们可以看到,用StingReader这个类不断去读取字符流中的数据,一直到读取完了。当解析到‘/’符号的时候表明这是一个标签的结尾,这时候我们就要执行parseEndTag结束一个完整的标签。

 public void parseEndTag(int start) throws Exception {
        StringBuffer temp = new StringBuffer();
        while (true) {
            char ch = this.getChar();
            if ('<' == ch) {
                ch = this.getChar();
                if ('/' != ch) {
                   // throw new ParserException("illegal tag:" + pos);
                }
            } else if (' ' == ch||'/' == ch) {

            }else if ('>' == ch) {
                break;
            } else {
                temp.append(ch);
            }
        }
   }

当我们
解析到的不是结束标签的时候,就要把
当前标签的内容收集并且打印出来。

public void parseText(int start) throws Exception {

                  while (true) {
                        char ch = this.getChar();
                        if (EOF == ch) {
                            this.ungetChar();
                            char data[] = this.makeString(start, pos);

                            break;
                        } else if ('<' == ch) {
                            //解析到 空 等各类标签后 循环解析到 < 为止, 计算进入时的字符间的内容
                            this.ungetChar();
                            char data[] = this.makeString(start, pos);
//                          if (data != null) {
//                              System.out.println(new String(data));
//                  //                       
//                          }
                            break;
                        }
                    }
        }
    public char[] makeString(int start, int end) throws Exception {
        int length = end - start;
        char data[] = new char[length];
        this.reader.reset();
        this.reader.skip(start);
        this.reader.read(data);
        String text = new String(data);

        if (text.trim().equals("")  ) {
            data = null;
        }
         System.out.println("[" + start + "," + end + "]Element: " + new String(data));
         printNode(text);//对于标签里面的属性,再进行解析并且打印
          return data;

}

 /*
         * 打印一个标签里面的属性
         * 具体场景可以根据
         */
        private void printNode(String text) throws IOException {
            Reader reader =new StringReader(text);
            char c = (char) reader.read();
            String temp="";
            boolean first = true;
            while (c != EOF) {
                if (c == ' ') {
                    if(first)
                        System.out.println(temp);
                    else 
                        System.out.println("Attribute:"+temp);
                    first = false;
                    temp = "";
                }
                temp += c;
                c = (char) reader.read();
            }    
        }

好了,接下来我们来运行程序,打印果如下:
这里写图片描述

我们看到,Element表示标签名,xml,span,button这些标签名都打印出来了。
然后有属性的标签,比如像button,里面的属性都收集过来打印出来了。
提供下完整代码地址:
https://github.com/preqel/Parser
我们已经完成了对xml的简单解析,但是还有些问题没解决:
1.嵌套标签的解析,父子元素关系。
2.对于注解符号的解析
这些内容放到后面有时间进行研究。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值