package com.edu.buu.test_XML;

//【下面使我们进行解析的XML文件,这边为简单起见,将test.xml保存于当前工程下,当然也可以将使用全部路径,关于异常的处理以及文件操作读者自行选择】

/**
    <?xml version="1.0" encoding="utf-8"?>
<bookstore>
	<book id="one">
		<name>《冰与火之歌》</name>
		<author>乔治.马丁</author>
		<price>89</price>
		<outline>《冰与火之歌》主要描述了在一片虚构的中世纪世界里所发生的
		一系列宫廷斗争、疆场厮杀、游历冒险和魔法抗衡的故事。
		在内容及风格上,《冰与火之歌》是现实生活的一面镜子,人性真实的写照。</outline>
	</book>
	<book id="two">
		<name>"Gone with the Wind"</name>
		<author>Margaret.Mitchell</author>
		<price>99</price>
		<language>English</language>
		<outline>《飘》 是美国女作家玛格丽特·米切尔(1900—1949)
		十年磨一剑的作品,也是惟一的作品。</outline>
	</book>
</bookstore>
   
    */
    
    /*
       【 可以看到的是我们的test.XML 文件包括一个根节点bookstore,一般这个根节点是不需要解析的,我们只从book节点开始解析,当然解析的目标也包括book节点的属性id以及id属性的值和book节点的子节点;还有一部分需要注意的是这边导入的包是org.w3c这个包】
    */
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class TestDOM {
	
	public static void main(String[] args){
		
		DocumentBuilderFactory documentBuilderFactory =
		                 DocumentBuilderFactory.newInstance();
		
		DocumentBuilder documentBuilder;
		
	try{
			
		documentBuilder = documentBuilderFactory.newDocumentBuilder();
	        //【我们需要Document的对象接收XML文件的传入】
		Document document = documentBuilder.parse("test.xml");
		
		NodeList bookList = document.getElementsByTagName("book");
		
		System.out.println("test.xml文件共有"+bookList.getLength()+"个book节点");
		
		System.out.println("===========下面使用for循环进行节点遍历=============");
		
		for(int i = 0; i < bookList.getLength(); i ++){
			
			Node bookNode = bookList.item(i);
			
			NamedNodeMap namedNodeMap = bookNode.getAttributes();
			
			System.out.println("第"+(i+1)+"个book节点共有"+namedNodeMap.getLength()+"个属性");
			//获取book节点的属性名以及属性值
			for(int j = 0;j < namedNodeMap.getLength();j ++){
				//*改进的遍历条件*:if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) 
				Node attributes = namedNodeMap.item(j);
				
				System.out.println("属性名:"+attributes.getNodeName());
				
				System.out.println("属性值:"+attributes.getNodeValue());
			}
			//获取book节点的子节点(用getChildNodes()方法)
				NodeList childNodeList = bookNode.getChildNodes();
				
				for(int k = 0; k < childNodeList.getLength();k ++){
					
					Node childNode = childNodeList.item(k);
					
					if(childNode.getNodeName()!="#text"){
					//【注意两个节点之间的空白部分也被算作一个节点,其值等于#text】
					System.out.println("第"+(k+1)+"个子节点名为:"+childNode.getNodeName());
					
					System.out.println("第"+(k+1)+"个子节点值为:"+childNode.getFirstChild().getTextContent());
					}
			}
		}
		
		System.out.println("==============结束for循环遍历==============");
		
		System.out.println();
		
		System.out.println("*************使用常规方法遍历**************");
		//【此方法在知道节点值但不知道节点的属性以及属性值的情况下使用比较方便】
		for(int m = 0; m < bookList.getLength(); m ++){
			
			Element element = (Element)bookList.item(m);
			
			String attributeID = element.getAttribute("id");
			
			System.out.println("第"+(m+1)+"本书的"+"id属性的值为:"+attributeID);
		}
	
		}catch(Exception e){
			//【注意有异常要及时处理,不要刻意回避,也不要嵌套过多异常,这样容易出错,刻意选择对异常进行集中处理】
			e.getMessage();
		}
	}
}

/**
【以下是解析结果】
test.xml文件共有2个book节点
=======================下面使用for循环进行节点遍历=========================
第1个book节点共有1个属性
属性名:id
属性值:one
第2个子节点名为:name
第2个子节点值为:《冰与火之歌》
第4个子节点名为:author
第4个子节点值为:乔治.马丁
第6个子节点名为:price
第6个子节点值为:89
第8个子节点名为:outline
第8个子节点值为:《冰与火之歌》主要描述了在一片虚构的中世纪世界里所发生的
		一系列宫廷斗争、疆场厮杀、游历冒险和魔法抗衡的故事。
		在内容及风格上,《冰与火之歌》是现实生活的一面镜子,人性真实的写照。
第2个book节点共有1个属性
属性名:id
属性值:two
第2个子节点名为:name
第2个子节点值为:"Gone with the Wind"
第4个子节点名为:author
第4个子节点值为:Margaret.Mitchell
第6个子节点名为:price
第6个子节点值为:99
第8个子节点名为:language
第8个子节点值为:English
第10个子节点名为:outline
第10个子节点值为:《飘》 是美国女作家玛格丽特·米切尔(1900—1949)
		十年磨一剑的作品,也是惟一的作品。
============================结束for循环遍历============================

****************************使用常规方法遍历*****************************
第1本书的id属性的值为:one
第2本书的id属性的值为:two

*/

    XML是一种可扩展标记语言,用于标记电子文件使其具有结构性的标记语言。标记是指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种的信息比如文章等。它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。是Internet环境中跨平台的、依赖于内容的技术,也是当今处理分布式结构信息的有效工具。

Java语言有自己的DOM解析器,对于普通XML文档的解析效率还是可以的。