首頁 後端開發 XML/RSS教程 android sax解析xml檔(二)

android sax解析xml檔(二)

Feb 17, 2017 pm 03:09 PM

在上篇文章中,简单介绍了sax解析xml的一种方式,它是继承defaultHandler方式,并重写其中的几个方法来实现的。

接下来说的第二种方式是用RootElement这个类来解析的,RootElement 内置了defaultHandler的子类,

RootElement 源码如下:


public class RootElement extends Element {

    final Handler handler = new Handler();

    /**
     * Constructs a new root element with the given name.
     *
     * @param uri the namespace
     * @param localName the local name
     */
    public RootElement(String uri, String localName) {
        super(null, uri, localName, 0);
    }

    /**
     * Constructs a new root element with the given name. Uses an empty string
     * as the namespace.
     *
     * @param localName the local name
     */
    public RootElement(String localName) {
        this("", localName);
    }

    /**
     * Gets the SAX {@code ContentHandler}. Pass this to your SAX parser.
     */
    public ContentHandler getContentHandler() {
        return this.handler;
    }

    class Handler extends DefaultHandler {

        Locator locator;
        int depth = -1;
        Element current = null;
        StringBuilder bodyBuilder = null;

        @Override
        public void setDocumentLocator(Locator locator) {
            this.locator = locator;
        }

        @Override
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
            int depth = ++this.depth;

            if (depth == 0) {
                // This is the root element.
                startRoot(uri, localName, attributes);
                return;
            }

            // Prohibit mixed text and elements.
            if (bodyBuilder != null) {
                throw new BadXmlException("Encountered mixed content"
                        + " within text element named " + current + ".",
                        locator);
            }

            // If we're one level below the current element.
            if (depth == current.depth + 1) {
                // Look for a child to push onto the stack.
                Children children = current.children;
                if (children != null) {
                    Element child = children.get(uri, localName);
                    if (child != null) {
                        start(child, attributes);
                    }
                }
            }
        }

        void startRoot(String uri, String localName, Attributes attributes)
                throws SAXException {
            Element root = RootElement.this;
            if (root.uri.compareTo(uri) != 0
                    || root.localName.compareTo(localName) != 0) {
                throw new BadXmlException("Root element name does"
                        + " not match. Expected: " + root + ", Got: "
                        + Element.toString(uri, localName), locator);
            }

            start(root, attributes);
        }

        void start(Element e, Attributes attributes) {
            // Push element onto the stack.
            this.current = e;

            if (e.startElementListener != null) {
                e.startElementListener.start(attributes);
            }

            if (e.endTextElementListener != null) {
                this.bodyBuilder = new StringBuilder();
            }
            
            e.resetRequiredChildren();
            e.visited = true;
        }

        @Override
        public void characters(char[] buffer, int start, int length)
                throws SAXException {
            if (bodyBuilder != null) {
                bodyBuilder.append(buffer, start, length);
            }
        }

        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            Element current = this.current;

            // If we've ended the current element...
            if (depth == current.depth) {
                current.checkRequiredChildren(locator);

                // Invoke end element listener.
                if (current.endElementListener != null) {
                    current.endElementListener.end();
                }

                // Invoke end text element listener.
                if (bodyBuilder != null) {
                    String body = bodyBuilder.toString();
                    bodyBuilder = null;

                    // We can assume that this listener is present.
                    current.endTextElementListener.end(body);
                }

                // Pop element off the stack.
                this.current = current.parent;
            }

            depth--;
        }
    }
}
登入後複製

以上是RootElement类得源码,从源码可以看出,它只是将defaultHandler简单的处理一下。


具体应用可以参照我写的测试源码


/**
	 * sax解析xml的第二种方式
	 * 		用XMLReader 也是sax的一种方式
	 * @return
	 */
	private String saxParseSecond(){
		//读取src下xml文件
		InputStream inputStream =
			 this.getClass().getClassLoader().getResourceAsStream("saxTest.xml");
		SAXParserFactory factory = SAXParserFactory.newInstance();
		try {
			SAXParser parse = factory.newSAXParser();
			XMLReader reader = parse.getXMLReader();
			reader.setContentHandler(getRootElement().getContentHandler());
			reader.parse(new InputSource(inputStream));
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}
登入後複製


/** 
     *  
     * @return 返回设置好处理机制的rootElement 
     */  
    private RootElement getRootElement(){  
          
        /*rootElement代表着根节点,参数为根节点的tagName*/  
        RootElement rootElement = new RootElement("classes");  
        /*获取一类子节点,并为其设置相应的事件 
         * 这里需要注意,虽然我们只设置了一次group的事件,但是我们文档中根节点下的所有 
         * group却都可以触发这个事件。 
         * */  
        Element groupElement = rootElement.getChild("group");  
        // 读到元素开始位置时触发,如读到<group>时  
        groupElement.setStartElementListener(new StartElementListener() {  
            @Override  
            public void start(Attributes attributes) {  
//                Log.i("TEST", "start");  
               String groupName =  attributes.getValue("name");
               String groupNum =  attributes.getValue("num");
               result = result+"groupName ="+groupName+"groupNum = "+groupNum+"\n";
            }  
        });  
        //读到元素结束位置时触发,如读到</group>时  
        groupElement.setEndElementListener(new EndElementListener() {  
            @Override  
            public void end() {  
            }  
        });  
        Element personElement = groupElement.getChild("person");
        //读取<person>标签触发
        personElement.setStartElementListener(new StartElementListener() {
			
			@Override
			public void start(Attributes attributes) {
				 String personName =  attributes.getValue("name");
	             String age =  attributes.getValue("age");
	             result = result+"personName ="+personName+"age = "+age+"\n";
			}
		});
        //读取</person>标签触发
        personElement.setEndElementListener(new EndElementListener() {
			
			@Override
			public void end() {
				
			}
		});
        
        Element chinese = personElement.getChild("chinese");  
//        chinese.setTextElementListener(new TextElementListener() {
//			
//			@Override
//			public void end(String body) {
//				// TODO Auto-generated method stub
//				
//			}
//			
//			@Override
//			public void start(Attributes attributes) {
//				// TODO Auto-generated method stub
//				
//			}
//		});
        // 读到文本的末尾时触发,这里的body即为文本的内容部分  
        chinese.setEndTextElementListener(new EndTextElementListener() {  
            @Override  
            public void end(String body) {  
            	Pattern p = Pattern.compile("\\s*|\t|\r|\n"); 
				Matcher m = p.matcher(body); 
				body = m.replaceAll(""); 
            	result = result+"chinese ="+body;
            }  
        });  
          
        Element english = personElement.getChild("english");  
        english.setEndTextElementListener(new EndTextElementListener() {  
            @Override  
            public void end(String body) {  
            	Pattern p = Pattern.compile("\\s*|\t|\r|\n"); 
				Matcher m = p.matcher(body); 
				body = m.replaceAll(""); 
               result = result+"english ="+body+"\n";
            }  
        });  
        return rootElement;  
          
    }
登入後複製



我们都知道通过SAXParser对象解析xml的方式,这里我们又从代码中看到了利用另一个对象XMLReader进行解析,那么两者到底有什么联系和区别呢?

其实SAXParser是在SAX 1.0 定义的,而XMLReader则是在2.0中才开始出现的。你可以认为XMLReader的出现是为了替代SAXParser解析的,两者本质上干的事情是一样的,只不过XMLReader的功能更加的强悍而已。

关于XMLReader的获取方式,除了通过SAXParser的getXMLReader方法获得之外,我们还可以通过以下两种方式。

XMLReader parser=XMLReaderFactory.createXMLReader(); (1)
XMLReader parser=XMLReaderFactory.createXMLReader(String className); (2)
登入後複製


 以上就是android sax解析xml文件(二)的内容,更多相关内容请关注PHP中文网(www.php.cn)!


本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

新報告對傳聞中的三星 Galaxy S25、Galaxy S25 Plus 和 Galaxy S25 Ultra 相機升級進行了嚴厲的評估 新報告對傳聞中的三星 Galaxy S25、Galaxy S25 Plus 和 Galaxy S25 Ultra 相機升級進行了嚴厲的評估 Sep 12, 2024 pm 12:23 PM

最近幾天,Ice Universe 不斷披露有關 Galaxy S25 Ultra 的詳細信息,人們普遍認為這款手機將是三星的下一款旗艦智慧型手機。除此之外,洩密者聲稱三星只計劃升級一台相機

三星 Galaxy S25 Ultra 洩漏了第一張渲染圖,傳聞中的設計變化被曝光 三星 Galaxy S25 Ultra 洩漏了第一張渲染圖,傳聞中的設計變化被曝光 Sep 11, 2024 am 06:37 AM

OnLeaks 現在與 Android Headlines 合作,首次展示了 Galaxy S25 Ultra,幾天前,他試圖從他的 X(以前的 Twitter)粉絲那裡籌集到 4,000 美元以上的資金,但失敗了。對於上下文,嵌入在 h 下面的渲染圖像

三星 Galaxy S24 FE 預計將以低於預期的價格推出,有四種顏色和兩種記憶體選項 三星 Galaxy S24 FE 預計將以低於預期的價格推出,有四種顏色和兩種記憶體選項 Sep 12, 2024 pm 09:21 PM

三星尚未就何時更新其 Fan Edition (FE) 智慧型手機系列提供任何提示。目前來看,Galaxy S23 FE 仍然是該公司的最新版本,於 2023 年 10 月年初推出。

新報告對傳聞中的三星 Galaxy S25、Galaxy S25 Plus 和 Galaxy S25 Ultra 相機升級進行了嚴厲的評估 新報告對傳聞中的三星 Galaxy S25、Galaxy S25 Plus 和 Galaxy S25 Ultra 相機升級進行了嚴厲的評估 Sep 12, 2024 pm 12:22 PM

最近幾天,Ice Universe 不斷披露有關 Galaxy S25 Ultra 的詳細信息,人們普遍認為這款手機將是三星的下一款旗艦智慧型手機。除此之外,洩密者聲稱三星只計劃升級一台相機

小米紅米 Note 14 Pro Plus 上市,成為首款配備 Light Hunter 800 相機的高通 Snapdragon 7s Gen 3 智慧型手機 小米紅米 Note 14 Pro Plus 上市,成為首款配備 Light Hunter 800 相機的高通 Snapdragon 7s Gen 3 智慧型手機 Sep 27, 2024 am 06:23 AM

Redmi Note 14 Pro Plus 現已正式成為去年 Redmi Note 13 Pro Plus 的直接後繼產品(亞馬遜售價 375 美元)。正如預期的那樣,Redmi Note 14 Pro Plus與Redmi Note 14和Redmi Note 14 Pro一起成為Redmi Note 14系列的主角。李

iQOO Z9 Turbo Plus:可能增強的系列旗艦產品已開始預訂 iQOO Z9 Turbo Plus:可能增強的系列旗艦產品已開始預訂 Sep 10, 2024 am 06:45 AM

OnePlus的姊妹品牌iQOO的2023-4年產品週期可能即將結束;儘管如此,該品牌已宣布 Z9 系列的開發尚未結束。它的最終版,也可能是最高端的 Turbo+ 變體剛剛按照預測發布。時間

IFA 2024 | AGM Pad P2 Active 作為搭載 Android 14 的可轉換堅固型平板電腦首次亮相 IFA 2024 | AGM Pad P2 Active 作為搭載 Android 14 的可轉換堅固型平板電腦首次亮相 Sep 08, 2024 am 06:30 AM

AGM Mobile 在 IFA 2024 上展示了最新平板電腦 Pad P2 Active,這也是首款採用強化黑橙色外殼的平板電腦。它被吹捧為適合戶外工作,因為它有一個 360° 翻轉環,可以在 n 時充滿支撐手柄。

從早期圖片來看,Oppo Find X8 的設計看起來像是蘋果 iPhone 16 Pro 和 OnePlus Open 的結合體 從早期圖片來看,Oppo Find X8 的設計看起來像是蘋果 iPhone 16 Pro 和 OnePlus Open 的結合體 Sep 28, 2024 am 06:04 AM

從歷史上看,除了2018 年6 月發布的初代Find X 之外,Oppo 都會在冬末或初春更新其旗艦產品「Find X」系列。一點在此刻。 H

See all articles