从任意数据结构生成XML解析器产生SAX事件

xml|生成xml|数据|数据结构

 在j2ee1.4标准教材里看到一个很有趣的例子,从任意数据结构生成XML解析器产生SAX事件.数据结构可以是文本文件,PDF格式文档等.关键是自己解析这些数据源.另外一个有意思的地方是观察者模式的应用.所以就粗糙的改了一下并完整到可以测试运行.观察者模式简略UML图:

具体实现 被观察者对象ParseXMLSubject类:
package test;

import java.io.*;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.*;

public class ParseXMLSubject implements XMLReader {
    ContentHandler handler;

    String nsu = "";
    Attributes atts = new AttributesImpl();
    String rootElement = "addressbook";
    String indent = "\n    ";

    public ParseXMLSubject(){

    }

    public ContentHandler getContentHandler() {
        return handler;
    }

    public void parse(InputSource input) throws IOException, SAXException {
        try {
            // Get an efficient reader for the file
            java.io.Reader r = input.getCharacterStream();
            BufferedReader br = new BufferedReader(r);

            // Read the file and display it's contents.
            String line = br.readLine();

            while (null != (line = br.readLine())) {
                if (line.startsWith("email:")) {
                    break;
                }
            }

            if (handler == null) {
                throw new SAXException("No content handler");
            }

            // Note:
            // We're ignoring setDocumentLocator(), as well
            handler.startDocument();
            handler.startElement(nsu, rootElement, rootElement, atts);

            output("email",  line);
            line = br.readLine();
            output("html", line);
            line = br.readLine();
            output("firstname",  line);
            line = br.readLine();
            output("lastname", line);
            line = br.readLine();
            output("work",  line);
            line = br.readLine();
            output("home", line);
            line = br.readLine();
            output("fax",  line);
            line = br.readLine();
            output("pager", line);
            line = br.readLine();
            output("cell",  line);
            handler.ignorableWhitespace("\n".toCharArray(), 0, // start index
                                        1 // length
                    );
            handler.endElement(nsu, rootElement, rootElement);
            handler.endDocument();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void parse(String systemId) throws IOException, SAXException {
    }

    public DTDHandler getDTDHandler() {
        return null;
    }

    public EntityResolver getEntityResolver() {
        return null;
    }

  public ErrorHandler getErrorHandler() {
        return null;
    }

    public boolean getFeature(String name) throws SAXNotRecognizedException,
            SAXNotSupportedException {
        return false;
    }

    public Object getProperty(String name) throws SAXNotRecognizedException,
            SAXNotSupportedException {
        return null;
    }

    public void setContentHandler(ContentHandler handler) {
        this.handler = handler;
    }

    public void setDTDHandler(DTDHandler handler) {
    }

    public void setEntityResolver(EntityResolver resolver) {
    }

    public void setErrorHandler(ErrorHandler handler) {
    }

    public void setFeature(String name, boolean value) throws
            SAXNotRecognizedException, SAXNotSupportedException {
    }

    public void setProperty(String name, Object value) throws
            SAXNotRecognizedException, SAXNotSupportedException {
    }

    void output(String name, String line) throws SAXException {
        int tmp = name.length();
        int startIndex=tmp+1;
        int textLength = line.length() - startIndex;
        String characters = line.substring(startIndex,line.length()-1);
        handler.ignorableWhitespace(indent.toCharArray(), 0, // start index
                                    indent.length());
        handler.startElement(nsu, name, name /*"qName"*/, atts);

        handler.characters(characters.toCharArray(), startIndex, textLength);
        handler.endElement(nsu, name, name);
    }

}

具体观察者对象: ConcreateObserver类
package test;

import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.*;
public class ConcreateObserver extends DefaultHandler {
    public ConcreateObserver() {
    }

    public void startElement(String uri,
                         String localName,
                         String qName,
                         Attributes attributes)
                  throws SAXException{
              System.out.println("startElement: "+localName);
          }
          public void characters(char[] ch,
                                 int start,
                                 int length)
                throws SAXException{
            System.out.println("characters: ");
            System.out.print(ch);
            System.out.println();
        }
}

测试类:TestMain
package test;
import java.io.*;
import org.xml.sax.InputSource;
public class TestMain {
    public TestMain() {
    }

    public static void main(String[] args) throws Exception {
        TestMain testmain = new TestMain();
        FileReader in = new FileReader(new File("d:\\AddressBookReaderLog01.txt"));

        ConcreateObserver observer=new ConcreateObserver();
        ParseXMLSubject parse = new ParseXMLSubject();
        parse.setContentHandler(observer);

        parse.parse(new InputSource(in));
    }
}

测试文本文档:AddressBookReaderLog01.txt

AddressBookReader01 ../samples/PersonalAddressBook.ldif
nickname: Fred
email: fred@barneys.house
html: TRUE
firstname: Fred
lastname: Flintstone
work: 999-Quarry
home: 999-BedrockLane
fax: 888-Squawk
pager: 777-pager
cell: 555-cell

另外一个也比较也有意思的地方就是具体观察者类从DefaultHandler 继承,该类是缺省适配器模式的应用.

时间: 2024-08-01 09:57:11

从任意数据结构生成XML解析器产生SAX事件的相关文章

C语言实现的XML解析器

最近做嵌入式开发,板子上面需要有解析XML的功能,理所当然地我就去网上找开源的来用.结果找来的要不是C++的,要不就是超级复杂的.像libxml,我统计了下解析一个40几KB的XML文件,居然动态申请内存100多次,对于没有mmu功能的arm7,真是无福消受了. 所以,我只能自己写一个来用了. 我写的这个xml解析器,非常简单,核心代码只有600多行.当然,功能也相对弱些,只支持ansi编码的xml文件,只能解析,不能生成. 整个解析器只用到了 若干条 EBNF文法 和 一个DFA状态机 (用来

TinyXML:一个优秀的C++ XML解析器(转载)

/* 读取和设置xml配置文件是最常用的操作,试用了几个C++的XML解析器,个人感觉TinyXML是使用起来最舒服的,因为它的API接口和Java的十分类似,面向对象性很好. TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译.这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树. DOM模型即文档对象模型,是将整个文档分成多个元素(如书.章.节.段等),并利用树型结构表示这些元素之间的顺序关系以及

tinyxml 常用的C++ XML解析器非常优秀_C 语言

读取和设置xml配置文件是最常用的操作,试用了几个C++的XML解析器,个人感觉TinyXML是使用起来最舒服的,因为它的API接口和Java的十分类似,面向对象性很好. TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译.这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树. DOM模型即文档对象模型,是将整个文档分成多个元素(如书.章.节.段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包

XML入门教程:XML 解析器

xml|教程|入门教程 如需读取.更新.创建或者操作某个XML文档,则需要XML解析器. 实例 解析XML文件 - 跨浏览器的实例 本例是一个跨浏览器的实例,把某个XML文档("note.xml")载入XML解析器. <html><body><script type="text/vbscript">set xmlDoc=CreateObject("Microsoft.XMLDOM")xmlDoc.async=&

微软xml解析器

XML解析器可以读取.更新.创建.操作一个XML文档. -------------------------------------------------------------------------------- 使用XML解析器 微软的XML解析器是和IE5.0+浏览器捆绑在一起的. 一旦你安装了IE5.0,那么就获得了XML解析器.这个浏览器除了被浏览器内部调用外,还可以在脚本中或者程序中调用.这个解析器的特点是支持与程序设计语言无关的编程模型,他支持以下技术: JavaScript,

XML指南——微软的XML解析器

    XML解析器可以读取.更新.创建.操作一个XML文档.使用XML解析器微软的XML解析器是和IE5.0+浏览器捆绑在一起的.一旦你安装了IE5.0,那么就获得了XML解析器.这个浏览器除了被浏览器内部调用外,还可以在脚本中或者程序中调用.这个解析器的特点是支持与程序设计语言无关的编程模型,他支持以下技术:JavaScript, VBScript, Perl, VB, Java, C++ 等等 W3C XML 1.0 和 XML DOM DTD 和 XML文档验证 如果浏览器使用JavaS

[Python]HTML/XML解析器Beautiful Soup

[简介] Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库.即HTML/XMLX的解析器. 它可以很好的处理不规范标记并生成剖析树(parse tree). 它提供简单又常用的导航(navigating),搜索以及修改剖析树的操作.它可以大大节省你的编程时间. [安装] 下载地址:点击打开链接 Linux平台安装: 如果你用的是新版的Debain或ubuntu,那么可以通过系统的软件包管理来安装: $ apt-get install Python-bs4 B

Android中XML文件的序列化生成与解析

首先,我把Person的实体类 package net.loonggg.test; public class Person { private int id; private String age; private String name; private String sex; private String address; public int getId() { return id; } public void setId(int id) { this.id = id; } public

Android中使用pull解析器操作xml文件的解决办法_Android

一.使用Pull解析器读取XML文件 除了可以使用SAX或DOM解析XML文件之外,大家也可以使用Android内置的Pull解析器解析XML文件. Pull解析器是一个开源的java项目,既可以用于android,也可以用于JavaEE.如果用在javaEE需要把其jar文件放入类路径中,因为Android已经集成进了Pull解析器,所以无需添加任何jar文件.android系统本身使用到的各种xml文件,其内部也是采用Pull解析器进行解析的. Pull解析器的运行方式与SAX 解析器相似.