什么是XML?
渣渣在这里也是初步了解了一下。Extentsible Markup Language(可扩展标记语言)的缩 写,是用来定义其它语言的一种元语言。我们打开每一个XML 文件都可以看出来他们的标签都是成对存在的(尴尬又是成对),我们对于XML 文件来说他的存储结构是一个倒着的树状结构,开始是一个根节点。
xml的用途:
存提供的储通信信息,相同的xml 文件可以连接不同的东西,包括不同的平台不同的编辑环境
解析xml文件:
读取xml 文件的内容,获取节点名,节点值,属性名和属性值。
常用的四种解析方式:DOM SAX DOM4J JDOM 。前两中是由官方提供的。
下面我们尝试着解析一个XML 文件
随意写了一个XML 文件
<?xml version="1.0" encoding="UTF-8"?>
<studentinfo>
<student id="1">
<name>jack</name>
<age>19</age>
<sex>man</sex>
</student>
<student id="2" name="sam">
<class>1</class>
<sex>man</sex>
<grade>2</grade>
</student>
</studentinfo>
我们先来了解几个接口
(1)DocumentBuilderFactroy
定义工厂API ,使得程序能够从XML文档获取生成DOM 对象数的解析器。
(2)DocumentBuilder
使用此API 可以从XML 中获取到一个document。此类的实例可以从 DocumentBuilderFactory.newDocumentBuilder()
方法获取。获取此类的实例之后,将可以从各种输入源解析 XML。
(3)Document
此接口表示整个HTML或者XML 文档,它是文档的树根并提供对文档数据的基本访问。
getElementByTag(String TagName):按文档的顺序返回包含在文档中的且具有给定标记名称的所有Element的NodeList。
import java.io.IOException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DomText {
/**
* @param args
* @throws ParserConfigurationException
* @throws IOException
* @throws SAXException
*/
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException {
// 获取DocumentBuilderFactory新实例
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建DocumentBuilder实例并且通过方法parse传入所要解析的XML 文件。获取一个document(org.w3c.dom)
Document bd = dbf.newDocumentBuilder().parse("book.xml");
/**
* 解析属性
*/
// 根据标签名获取标签集合 NodeList(org.w3c.dom)类型
NodeList nodelist = bd.getElementsByTagName("student");
System.out.println("总共有" + nodelist.getLength() + "个学生");
for (int i = 0; i < nodelist.getLength(); i++) {
// 获取NodeList中对应的mouyixian
Node node = nodelist.item(i);
// 获取对应的节点的属性
NamedNodeMap nnm = node.getAttributes();
System.out.println("第" + (i + 1) + "学生共有" + nnm.getLength() + "属性");
System.out.print("属性有:");
for (int j = 0; j < nnm.getLength(); j++) {
Node nd = nnm.item(j);
System.out.print(" " + nd.getNodeName());
}
/**
* 解析子节点
*/
System.out.println(" ");
System.out.println("获取节点的值");
// 获取此时对应项的子节点,返回子节点集合 NodeList 类型
NodeList nl = node.getChildNodes();
for (int k = 0; k < nl.getLength(); k++) {
// 筛选显示
if (nl.item(k).getNodeType() == Node.ELEMENT_NODE)
{ System.out.print(" " + nl.item(k).getNodeName());
//按照我们所想象的如果获取子节点的value或许可以这样做
System.out.print(": "+nl.item(k).getNodeValue());
}
<span style="font-family: Arial, Helvetica, sans-serif;"> }</span>
System.out.println(" ");
}
}
}
所在上面的代码其中有一个筛选的部分。对于DOM 文件存在以下几种常用的结点类型:
那么对于要获取节点的value该如何去做,刚开始认为采用函数getNodeValue(),就可以 了,但是运行结果出来却是null。
其实答案在上面的表格就很明显,直接采用nl.item(k).getNodeValue()获取到的是Element 节点 的value固然是null
在解析的时候他会将<> XXX</>之间的取值认为是一个子节点,所以我们在取值的时候应该采用子节点的方式,所以采用如下的代码:
第一种:
System.out.print(": "+nl.item(k).getFirstChild().getNodeValue());
第二种:
System.out.print(": "+nl.item(k).getTextContent());
这两种都可以获取到正确的value 但是两者有什么区别?我们改变一下最初我们的XML 文件,来进行对比。
我们在第一个student的那么之间加入子节点<front></front>
我们运行以下程序看一下两者结果的区别:
第一种:
值是null,因为此时第一个孩子结点是front,他是一个element节点 所以他的value是null
第二种:
正确获取!!!!!
Java API中给出了这样的解释:
以在XML 进行解析的时候,会将空格和换行符也会认为是一个结点,会已#text 输出,所以我们需要进行筛选,去掉这一项。
总结一个错误:
A pseudo attribute name is expected. 错误表XML 文件中存在错误,文件不规范,无法查找到。