XML 解析

我们先了解xml有什么用,它是一个通用的数据交互的格式,对,就是做数据交互的,我们知道JSON也是做数据交互的。怎么来理解这个数据交互呢,例如我们现在有一个java项目,后台是java写的,前端是js,现在有个请求,需要查询这个order的信息,我先从数据库查出来这条数据,搭orm映射,存放到一个javaBean中,之后我们需要将这个javaBean的数据传递到前端js来接受,后台java的语法,js是不认识这个东西,所以我们需要定一个达成共识的标准,按照这种标准的语法来写,java认识,js也认识,这样问题就解决了,这种标准的作用的就做数据交互。

json和xml 比较  json相对比较轻,写法也简单,像后台和页面的交互,这种数据量不大,用json来实现,但是如果是不同系统进行对接,这个时候就需要使用xml,我们平时都是使用webService来进行不同系统的交互,xml就是webService的重要组成部分。

xml解析的分为两种方式:

1)dom:基于xml文件树结构进行解析,每个元素都是node。

2)SAX:基于事件进行解析。

1.DOM解析

<?xml version="1.0" encoding="UTF-8"?>
<employess>
	<employes>
		<name>zhangsan</name>
		<!-- 0为男性 1位女性 -->
		<sex>0</sex>
		<age>22</age>		
	</employes>
	<employes>
		<name>xiangli</name>
		<!-- 0为男性 1位女性 -->
		<sex>1</sex>
		<age>20</age>		
	</employes>	
</employess>

public class TestDom {
	public static void main(String[] args) throws ParserConfigurationException, Exception{
		ClassLoader classLoader = TestDom.class.getClassLoader();
		InputStream resourceAsStream = classLoader.getResourceAsStream("test.xml");
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		
		DocumentBuilder builder= factory.newDocumentBuilder();
		Document document = builder.parse(resourceAsStream);
		NodeList employess = document.getElementsByTagName("employes");
		for (int i = 0; i < employess.getLength(); i++) {
			System.out.println("第["+i+"]个员工");
			System.out.println("员工姓名:"+document.getElementsByTagName("name").item(i).getFirstChild().getNodeValue());
			System.out.println("员工性别:"+document.getElementsByTagName("sex").item(i).getFirstChild().getNodeValue());
			System.out.println("员工年龄:"+document.getElementsByTagName("age").item(i).getFirstChild().getNodeValue());
		}
	}
}
第[0]个员工
员工姓名:zhangsan
员工性别:0
员工年龄:22
第[1]个员工
员工姓名:xiangli
员工性别:1
员工年龄:20

我们只需要拿到Document对象,就可以根据API对它的每个节点进行增删改查,写法比较简单

2.SAX解析

SAX解析是基于事件,我们需要继承DefaultHandler ,然后重写它的一些方法,这些方法会在解析xml触发一些特定事件的时候调用,我们可以在方法里面做一些数据保存的操作。

public class DefaultHandler
    implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler
{

    /**
     * Receive notification of the beginning of the document.
     *
     * <p>By default, do nothing.  Application writers may override this
     * method in a subclass to take specific actions at the beginning
     * of a document (such as allocating the root node of a tree or
     * creating an output file).</p>
     *
     * @exception org.xml.sax.SAXException Any SAX exception, possibly
     *            wrapping another exception.
     * @see org.xml.sax.ContentHandler#startDocument
     */
    public void startDocument ()
        throws SAXException
    {
        // 开始解析xml 调用此方法 (non-Javadoc)
    }

    /**
     * Receive notification of the end of the document.
     *
     * <p>By default, do nothing.  Application writers may override this
     * method in a subclass to take specific actions at the end
     * of a document (such as finalising a tree or closing an output
     * file).</p>
     *
     * @exception org.xml.sax.SAXException Any SAX exception, possibly
     *            wrapping another exception.
     * @see org.xml.sax.ContentHandler#endDocument
     */
    public void endDocument ()
        throws SAXException
    {
        // 结束解析文档,即解析根元素结束标签时调用该方法
    }

    /**
     * Receive notification of the end of a Namespace mapping.
     *
     * <p>By default, do nothing.  Application writers may override this
     * method in a subclass to take specific actions at the end of
     * each prefix mapping.</p>
     *
     * @param prefix The Namespace prefix being declared.
     * @exception org.xml.sax.SAXException Any SAX exception, possibly
     *            wrapping another exception.
     * @see org.xml.sax.ContentHandler#endPrefixMapping
     */
    public void endPrefixMapping (String prefix)
        throws SAXException
    {
        // no op
    }

    /**
     * Receive notification of the start of an element.
     *
     * <p>By default, do nothing.  Application writers may override this
     * method in a subclass to take specific actions at the start of
     * each element (such as allocating a new tree node or writing
     * output to a file).</p>
     *
     * @param uri The Namespace URI, or the empty string if the
     *        element has no Namespace URI or if Namespace
     *        processing is not being performed.
     * @param localName The local name (without prefix), or the
     *        empty string if Namespace processing is not being
     *        performed.
     * @param qName The qualified name (with prefix), or the
     *        empty string if qualified names are not available.
     * @param attributes The attributes attached to the element.  If
     *        there are no attributes, it shall be an empty
     *        Attributes object.
     * @exception org.xml.sax.SAXException Any SAX exception, possibly
     *            wrapping another exception.
     * @see org.xml.sax.ContentHandler#startElement
     */
    public void startElement (String uri, String localName,
                              String qName, Attributes attributes)
        throws SAXException
    {
        // 开始解析每个元素调用这个方法
    }

    /**
     * Receive notification of the end of an element.
     *
     * <p>By default, do nothing.  Application writers may override this
     * method in a subclass to take specific actions at the end of
     * each element (such as finalising a tree node or writing
     * output to a file).</p>
     *
     * @param uri The Namespace URI, or the empty string if the
     *        element has no Namespace URI or if Namespace
     *        processing is not being performed.
     * @param localName The local name (without prefix), or the
     *        empty string if Namespace processing is not being
     *        performed.
     * @param qName The qualified name (with prefix), or the
     *        empty string if qualified names are not available.
     * @exception org.xml.sax.SAXException Any SAX exception, possibly
     *            wrapping another exception.
     * @see org.xml.sax.ContentHandler#endElement
     */
    public void endElement (String uri, String localName, String qName)
        throws SAXException
    {
        // 每个元素结束的时候都会调用该方法
    }

    /**
     * Receive notification of character data inside an element.
     *
     * <p>By default, do nothing.  Application writers may override this
     * method to take specific actions for each chunk of character data
     * (such as adding the data to a node or buffer, or printing it to
     * a file).</p>
     *
     * @param ch The characters.
     * @param start The start position in the character array.
     * @param length The number of characters to use from the
     *               character array.
     * @exception org.xml.sax.SAXException Any SAX exception, possibly
     *            wrapping another exception.
     * @see org.xml.sax.ContentHandler#characters
     */
    public void characters (char ch[], int start, int length)
        throws SAXException
    {
        // 解析到每个元素的内容时会调用此方法
    }

}

public static void main(String[] args) throws Exception, Exception {
		SAXParserFactory factory = SAXParserFactory.newInstance();
		String path = TestSAX.class.getClassLoader().getResource("test.xml").getPath();
		SAXParser saxParser = factory.newSAXParser();
		MyHandler myHandler = new MyHandler("name");
		saxParser.parse(path, myHandler);
		List<Map<String, String>> list = myHandler.getList();
		System.out.println(JSON.toJSONString(list));
}
开始解析 xml
开始解析  元素
正在解析每个元素内容
开始解析  元素
正在解析每个元素内容
开始解析  元素
正在解析每个元素内容
-----name zhangsan
元素内容 解析结束
正在解析每个元素内容
正在解析每个元素内容
开始解析  元素
正在解析每个元素内容
元素内容 解析结束
正在解析每个元素内容
开始解析  元素
正在解析每个元素内容
元素内容 解析结束
正在解析每个元素内容
元素内容 解析结束
正在解析每个元素内容
开始解析  元素
正在解析每个元素内容
开始解析  元素
正在解析每个元素内容
-----name xiangli
元素内容 解析结束
正在解析每个元素内容
正在解析每个元素内容
开始解析  元素
正在解析每个元素内容
元素内容 解析结束
正在解析每个元素内容
开始解析  元素
正在解析每个元素内容
元素内容 解析结束
正在解析每个元素内容
元素内容 解析结束
正在解析每个元素内容
元素内容 解析结束
文档解析  结束
[{"name":"zhangsan"},{"name":"xiangli"}]

3.JDOM解析

JDOM的API中大量使用了collections类,它自身不带有解释器,一般使用SAX解释器

public static void main(String[] args) {
		String path = MyJDOM.class.getClassLoader().getResource("test1.xml").getPath();
		try {
			parserXML(path);
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//解析xml
	public static void parserXML(String path) throws JDOMException, IOException {
		SAXBuilder saxBuilder = new SAXBuilder();
		Document build = saxBuilder.build(path);
		Element root = build.getRootElement();
		List<Element> children = root.getChildren("person");
		for (Element element : children) {
			List<Element> children2 = element.getChildren();
			for (Element elem : children2) {
				System.out.println(elem.getName()+":"+elem.getValue());
			}
		}
	}
	

4.DOM4J解析

DOM4J的API是最复杂的,也是性能最好的,甚至就连sun公司也使用 DOM4j ,缺点就是可移植性太差

public static void main(String[] args) throws DocumentException {
		InputStream resourceAsStream = MyDOM4J.class.getClassLoader().getResourceAsStream("test1.xml");
		SAXReader saxReader = new SAXReader();
		Document read = saxReader.read(resourceAsStream);
		Element rootElement = read.getRootElement();
		System.out.println("当前节点名称 :"+rootElement.getName());
		listNodes(rootElement);
	}
	
	//遍历当前节点下的所有节点  
    public static void listNodes(Element node){  
        System.out.println("当前节点的名称:" + node.getName());  
        //首先获取当前节点的所有属性节点  
        List<Attribute> list = node.attributes();  
        //遍历属性节点  
        for(Attribute attribute : list){  
            System.out.println("属性"+attribute.getName() +":" + attribute.getValue());  
        }  
        //如果当前节点内容不为空,则输出  
        if(!(node.getTextTrim().equals(""))){  
             System.out.println( node.getName() + ":" + node.getText());    
        }  
        //同时迭代当前节点下面的所有子节点  
        //使用递归  
        Iterator<Element> iterator = node.elementIterator();  
        while(iterator.hasNext()){  
            Element e = iterator.next();  
            listNodes(e);  
        }  
    }
当前节点名称 :persons
当前节点的名称:persons
当前节点的名称:person
当前节点的名称:name
name:java小强
当前节点的名称:sex
sex:man
当前节点的名称:age
age:23


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值