编程语言
首页 > 编程语言> > java – 有没有办法使用SAX Parser使用Visitor模式?

java – 有没有办法使用SAX Parser使用Visitor模式?

作者:互联网

我对此很好奇:如果我需要使用Sax解析器来提高效率(这是一个很大的文件).通常我使用这样的东西:

public class Example extends DefaultHandler
{
    private Stack stack = new Stack ();

    public void startElement (String uri, String local, String qName, Attributes atts) throws SAXException
    {
        stack.push (qName);
    }

    public void endElement (String uri, String local, String qName) throws SAXException
    {
        if ("line".equals (qName))
            System.out.println ();

        stack.pop ();
    }

    public void characters (char buf [], int offset, int length) throws SAXException
    {
        if (!"line".equals (stack.peek ()))
            return;

        System.out.write (new String (buf, offset, length));
    }
}

例子来自here.

Sax已经是一个访问者模式的实现,但在我的情况下,我只需要根据元素本身的性质来获取每个元素的内容并对其进行一些操作.

我的典型XML文件类似于:

<?xml version="1.0" encoding="utf-8"?>
<labs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <auth>
        <uid> </uid>
        <gid> </gid>
        <key> </key>
    </auth>
    <campaign>
        <sms>
            <newsletter>206</newsletter>
            <message>
                <from>Da Definire</from>
                <subject>Da definire</subject>
                <body><![CDATA[Testo Da Definire]]></body>
            </message>
            <delivery method="manual"></delivery>
            <recipients>
                <db>276</db>
                <filter>
                    <test>1538</test>
                </filter>
                <new_recipients>
                    <csv_file>Corso2012_SMS.csv</csv_file>
                </new_recipients>
            </recipients>
        </sms>
    </campaign>
</labs>

当我在csv_file节点时,我需要获取文件名并从该文件上传用户,如果我在过滤器/测试中,我需要检查过滤器是否存在等等.
有没有办法将访客模式应用于SAX?

解决方法:

你可以简单地得到一个Map< String,ElementHandler>在您的SAX解析器中,并允许为元素名称注册ElementHandlers.假设您只对叶元素感兴趣:

>每次元素启动时,您会查看地图中是否存在此元素名称的处理程序,并清除缓冲区.
>每次调用characters()时,都会将字符附加到缓冲区(如果有前一个元素的处理程序)
>每次元素结束时,如果有前一个元素启动的处理程序,则使用缓冲区的内容调用处理程序

这是一个例子:

private ElementHandler currentHandler;
private StringBuilder buffer = new StringBuilder();
private Map<String, ElementHandler> handlers = new HashMap<String, ElementHandler>();

public void registerHandler(String qName, ElementHandler handler) {
    handlers.put(qName, handler);
}    

public void startElement (String uri, String local, String qName, Attributes atts) throws SAXException {
    currentHandler = handlers.get(qName);
    buffer.delete(0, buffer.length());
}

public void characters (char buf [], int offset, int length) throws SAXException {
    if (currentHandler != null) {
        buffer.append(buf, offset, length);
    }
}

public void endElement (String uri, String local, String qName) throws SAXException {
    if (currentHandler != null) {
        currentHandler.handle(buffer.toString();
    }
}

标签:java,sax,saxparser
来源: https://codeday.me/bug/20190709/1415113.html