<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 56, comments - 77, trackbacks - 0, articles - 1
      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    快速與簡(jiǎn)單并非天生不可兼得, 相反, 簡(jiǎn)單的東西應(yīng)該是快速的


    在使用 SAX 解析 XML 的過(guò)程中, 碰到了以下問(wèn)題:
    1. SAX Handler 并沒(méi)有想象中快, 尤其是文件比較大的時(shí)候
    2. SAX Handler 編寫(xiě)容易出錯(cuò), 因?yàn)樾枰獏^(qū)別不同的元素, 需要很多判斷才能拿到自己想要的信息
    3. 沒(méi)有統(tǒng)一的方法獲取SAX Handler解析出來(lái)的信息
    這實(shí)際上反映了目前SAX Handler接口定義中缺失的三種能力: Stoppable, Subscribable, 和 Reportable

    1, Stoppable


    缺省情況下SAX Parser會(huì)解析整個(gè)文件, 即使你已經(jīng)取得了足夠的你想要的信息, 但解析不會(huì)停止, 這就是感覺(jué)SAX Parser在解析大文件的時(shí)候不是很快的原因

    只有異常才能阻止SAX Parser繼續(xù)解析, 所以解決方法很簡(jiǎn)單:

    a). 定義接口:

    public interface Stoppable {

        boolean canStop();

    }

    b). 缺省實(shí)現(xiàn):

    public abstract class EnhancedHandler extends DefaultHandler implements Reportable {

        private boolean canStop;

        public boolean canStop() {  return canStop;    }

        protected void stop() { canStop = true; }  //call this method whensubclass objects get enough information.

    }

    c). 當(dāng)且只當(dāng)所有SAX Handler都可以停止的時(shí)候, 拋出異常:

    public class CompositeEnhancedHandler extends DefaultHandler {

        private static final RuntimeException SHOULD_STOP_EXCEPTION = newShouldStopParsingException();

        private final EnhancedHandler[] handlers;

        publicCompositeEnhancedHandler(EnhancedHandler... handlers) {

            this.handlers = handlers;

        }

        public void characters(char[] ch, int start, int length) throws SAXException {

            for (EnhancedHandler handler : handlers) { handler.characters(ch, start,length); }

            throwExceptionIfCanStop();

        }

        public void endElement(String uri, String localName,String qName) throws SAXException {

            for (EnhancedHandler handler : handlers) { handler.endElement(uri, localName,qName); }

            throwExceptionIfCanStop();

        }

        public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {

            for (EnhancedHandler handler : handlers) { handler.startElement(uri,localName, qName, attributes); }

            throwExceptionIfCanStop();

        }

        private void throwExceptionIfCanStop() {

            for (EnhancedHandler handler : handlers) {  if (!handler.canStop()) { return; } }

            throw SHOULD_STOP_EXCEPTION;

        }

    }

    d). SAX Parser 捕獲異常:

    CompositeEnhancedHandler handler = newCompositeEnhancedHandler(new Handler1(), new Handler2());

    try {

        SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();

        saxParser.parse(new File("england.xml"), handler);

    } catch (ShouldStopParsingException se) {

        // All handlers got enough information, just stop parsing.

     

    2. Subscribable


    不能指定只處理特定元素的能力的缺乏, 使得SAX Handler難以編寫(xiě)且易于出錯(cuò),  不得不判斷當(dāng)前元素的名稱, 是否正在處理特定的元素等, 這使得每個(gè)Handler都在重復(fù)這些邏輯相似的代碼.

    解決方法是提供一個(gè)額外的中間層, 詢問(wèn)SAX Handler對(duì)哪個(gè)元素感興趣. 該中間層只會(huì)向每個(gè)SAX Handler發(fā)送它們感興趣的元素信息. (也可以采用每個(gè)SAX Handler向中間層注冊(cè)感興趣信息的方法, 但比較復(fù)雜, ESAX采用前者)

    a). 定義接口:

    public interface Subscribable {

        String subscribe();

    }


    b). 中間層 CompositeEnhancedHandler:

    public class CompositeEnhancedHandler extends DefaultHandler{

        private final AddableMap mapping = new AddableMap();

        private List<EnhancedHandler> currentHandlers;

        publicCompositeEnhancedHandler(EnhancedHandler... handlers) {

            ... ...

            for (EnhancedHandler handler : handlers) {  mapping.get(handler.subscribe()).add(handler); }

        }

        public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {

            currentHandlers = mapping.get(qName);

            for (EnhancedHandler handler : currentHandlers) { handler.startElement(uri,localName, qName, attributes); }

            ... ...

        }

        public void characters(char[] ch, int start, int length) throws SAXException {

            for (EnhancedHandler handler : currentHandlers) { handler.characters(ch, start,length); }

            ... ...

        }

     

        public void endElement(String uri, String localName,String qName) throws SAXException {

            for (EnhancedHandler handler : currentHandlers) { handler.endElement(uri, localName,qName); }

            ... ...

        }

        private static class AddableMap {

            private Map<String, List<EnhancedHandler>>container = new HashMap<String, List<EnhancedHandler>>();

            public List<EnhancedHandler>get(String qname) {

                if (!container.containsKey(qname)) { container.put(qname, new ArrayList<EnhancedHandler>()); }

                return container.get(qname);

            }

        }

    }

     

    3. Reportable


    DOM提供了很方便的方法供提取特定信息, 但SAX Handler缺失了這項(xiàng)能力,  感興趣的信息被藏在每個(gè)Handler內(nèi)部

    ESAX提供的解決方法是"收集參數(shù)模式"

    a). 定義接口:

    public interface Reportable {

        void report(Map resultSet);

    }

    b). 缺省支持:

    public abstract class EnhancedHandler extends DefaultHandler implements Reportable,Stoppable, Subscribable {

        ... ...

    }

    public class CompositeEnhancedHandler extends DefaultHandler implements Reportable{

        public void report(Map resultSet) {

            for (EnhancedHandler handler : handlers) { handler.report(resultSet); }

        }

    }



    最終, ESAX 為 原始的 SAX Handler 補(bǔ)足了 可中止的能力, 可訂閱的能力, 可匯報(bào)的能力, 使得比原始的SAX Handler更快, 比DOM接口更簡(jiǎn)單, 更易于編程

    一個(gè)簡(jiǎn)單的例子可參見(jiàn):

    http://jade-stone-suite.googlecode.com/svn/trunk/JS.ESax/test/jade/stone/esax/sample/FACupHandler.java

    測(cè)試用例參見(jiàn):

    http://jade-stone-suite.googlecode.com/svn/trunk/JS.ESax/test/jade/stone/esax/test/CompositeEnhancedHandlerTest.java


    最終的缺省實(shí)現(xiàn)可參見(jiàn):

    http://jade-stone-suite.googlecode.com/svn/trunk/JS.ESax/src/jade/stone/esax/support/EnhancedHandler.java

    http://jade-stone-suite.googlecode.com/svn/trunk/JS.ESax/src/jade/stone/esax/support/CompositeEnhancedHandler.java

    項(xiàng)目主頁(yè):

    http://jade-stone-suite.googlecode.com/svn/trunk/JS.ESax/



    評(píng)論

    # re: Enhanced SAX Handler :比 DOM 還簡(jiǎn)單的 SAX Handler  回復(fù)  更多評(píng)論   

    2007-05-22 13:09 by bitiwyh
    看上去似乎不錯(cuò)...
    學(xué)習(xí)一下.

    Stopable的樣例代碼有錯(cuò)
    b). 缺省實(shí)現(xiàn):

    public abstract class EnhancedHandler extends DefaultHandler implements Reportable {

    Stopable?

    不過(guò),牛牛們都說(shuō),不能用異常控制流程啊......

    # re: Enhanced SAX Handler :比 DOM 還簡(jiǎn)單的 SAX Handler  回復(fù)  更多評(píng)論   

    2007-05-22 15:38 by 切爾斯基
    有沒(méi)有不用異常的好方法推薦? 我找了半天沒(méi)找到, 除非自己寫(xiě) SAXParser.parse()了, 呵呵

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 91麻豆精品国产自产在线观看亚洲| 国产成人一区二区三区免费视频| 精品香蕉在线观看免费| 97视频热人人精品免费| 国产精品免费小视频| 久久久久亚洲精品中文字幕| 亚洲国产精品线在线观看| 久久久久精品国产亚洲AV无码| 亚洲av成本人无码网站| 中文字幕在线免费播放| 精品免费人成视频app| 日韩免费观看的一级毛片| 中文字幕亚洲一区二区va在线| 久久亚洲日韩精品一区二区三区 | 日产国产精品亚洲系列| 亚洲日本va在线视频观看| 亚洲国产美女精品久久| 国产偷国产偷亚洲高清在线| 日本不卡免费新一区二区三区| 91免费精品国自产拍在线不卡| 亚洲美日韩Av中文字幕无码久久久妻妇| 日本亚洲欧洲免费天堂午夜看片女人员 | 久久亚洲私人国产精品vA| AV激情亚洲男人的天堂国语| 国产日韩一区二区三免费高清| 日本免费网址大全在线观看| 亚洲免费视频一区二区三区| 亚洲网红精品大秀在线观看| 无忧传媒视频免费观看入口| 亚洲视频在线观看免费视频| 亚洲成A∨人片天堂网无码| 亚洲美女aⅴ久久久91| 一出一进一爽一粗一大视频免费的 | 一级毛片a女人刺激视频免费| aⅴ免费在线观看| 亚洲黄黄黄网站在线观看| 亚洲电影在线播放| 一出一进一爽一粗一大视频免费的| 日韩精品无码区免费专区| 亚洲AV无码一区二区三区DV| 自拍偷自拍亚洲精品播放|