Home Backend Development XML/RSS Tutorial android sax parses xml files (2)

android sax parses xml files (2)

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--;
        }
    }
}
Copy after login

以上是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;
	}
Copy after login


/** 
     *  
     * @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;  
          
    }
Copy after login



我们都知道通过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)
Copy after login


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


Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

New report delivers damning assessment of rumoured Samsung Galaxy S25, Galaxy S25 Plus and Galaxy S25 Ultra camera upgrades New report delivers damning assessment of rumoured Samsung Galaxy S25, Galaxy S25 Plus and Galaxy S25 Ultra camera upgrades Sep 12, 2024 pm 12:23 PM

In recent days, Ice Universe has been steadily revealing details about the Galaxy S25 Ultra, which is widely believed to be Samsung's next flagship smartphone. Among other things, the leaker claimed that Samsung only plans to bring one camera upgrade

Samsung Galaxy S25 Ultra leaks in first render images with rumoured design changes revealed Samsung Galaxy S25 Ultra leaks in first render images with rumoured design changes revealed Sep 11, 2024 am 06:37 AM

OnLeaks has now partnered with Android Headlines to provide a first look at the Galaxy S25 Ultra, a few days after a failed attempt to generate upwards of $4,000 from his X (formerly Twitter) followers. For context, the render images embedded below h

Samsung Galaxy S24 FE billed to launch for less than expected in four colours and two memory options Samsung Galaxy S24 FE billed to launch for less than expected in four colours and two memory options Sep 12, 2024 pm 09:21 PM

Samsung has not offered any hints yet about when it will update its Fan Edition (FE) smartphone series. As it stands, the Galaxy S23 FE remains the company's most recent edition, having been presented at the start of October 2023. However, plenty of

New report delivers damning assessment of rumoured Samsung Galaxy S25, Galaxy S25 Plus and Galaxy S25 Ultra camera upgrades New report delivers damning assessment of rumoured Samsung Galaxy S25, Galaxy S25 Plus and Galaxy S25 Ultra camera upgrades Sep 12, 2024 pm 12:22 PM

In recent days, Ice Universe has been steadily revealing details about the Galaxy S25 Ultra, which is widely believed to be Samsung's next flagship smartphone. Among other things, the leaker claimed that Samsung only plans to bring one camera upgrade

Xiaomi Redmi Note 14 Pro Plus arrives as first Qualcomm Snapdragon 7s Gen 3 smartphone with Light Hunter 800 camera Xiaomi Redmi Note 14 Pro Plus arrives as first Qualcomm Snapdragon 7s Gen 3 smartphone with Light Hunter 800 camera Sep 27, 2024 am 06:23 AM

The Redmi Note 14 Pro Plus is now official as a direct successor to last year'sRedmi Note 13 Pro Plus(curr. $375 on Amazon). As expected, the Redmi Note 14 Pro Plus heads up the Redmi Note 14 series alongside theRedmi Note 14and Redmi Note 14 Pro. Li

iQOO Z9 Turbo Plus: Reservations begin for the potentially beefed-up series flagship iQOO Z9 Turbo Plus: Reservations begin for the potentially beefed-up series flagship Sep 10, 2024 am 06:45 AM

OnePlus'sister brand iQOO has a 2023-4 product cycle that might be nearlyover; nevertheless, the brand has declared that it is not done with itsZ9series just yet. Its final, and possibly highest-end,Turbo+variant has just beenannouncedas predicted. T

Oppo Find X8 design looks like a cross between Apple iPhone 16 Pro and OnePlus Open in early images Oppo Find X8 design looks like a cross between Apple iPhone 16 Pro and OnePlus Open in early images Sep 28, 2024 am 06:04 AM

Historically, Oppo has refreshed its flagship 'Find X' series in late winter or early spring, save for the original Find X that it announced in June 2018. To that end, the Find X7 and Find X7 Ultra are barely more than six months old at this point. H

How do you parse and process HTML/XML in PHP? How do you parse and process HTML/XML in PHP? Feb 07, 2025 am 11:57 AM

This tutorial demonstrates how to efficiently process XML documents using PHP. XML (eXtensible Markup Language) is a versatile text-based markup language designed for both human readability and machine parsing. It's commonly used for data storage an

See all articles