Java – is there any way to use Sax parser and visitor mode?

I'm curious about this: if I need to use a Sax parser to improve efficiency (this is a big file) Usually I use something like this:

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 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));
    }
}

Example from here

Sax is already an implementation of visitor pattern, but in my case, I only need to get the content of each element according to the nature of the element itself and do some operations on it

My typical XML file is similar to:

<?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>

When I was in CSV_ File node, I need to get the file name and upload the user from the file. If I am in the filter / test, I need to check whether the filter exists, etc Is there a way to apply guest mode to Sax?

Solution

You can simply get a map < string, elementhandler > in your sax parser and allow elementhandlers to be registered for element names Suppose you are only interested in leaf elements:

>Each time the element starts, you will check whether there is a handler for this element name in the map and clear the buffer. > Every time characters() is called, characters are appended to the buffer (if there is a handler for the previous element) > at the end of each element, if there is a handler started by the previous element, the handler is called using the contents of the buffer

Here is an example:

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,Attributes atts) throws SAXException {
    currentHandler = handlers.get(qName);
    buffer.delete(0,buffer.length());
}

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

public void endElement (String uri,String qName) throws SAXException {
    if (currentHandler != null) {
        currentHandler.handle(buffer.toString();
    }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>