xml解析器
如何操作XML文档
xml文档也是数据的一种,对数据的操作也不外乎是“曾删改查”(CRUD)。
XML解析技术
解析方式分为两种:
1.DOM(Document Object Model)
2.SAX(Simple API for XML)
两种解析都是为跨语言解析方式。
DOM是W3C组织提供的解析XML文档的标准接口,而SAX是社区讨论的产物,是一种事实上的标准。
DOM和SAX只是定义了一些接口,以及某些接口的缺省实现,而这个缺省实现只是用空方法来实现接口。一个应用程序如果需要DOM或SAX来访问XML文档,还需要一个实现了DOM或SAX的解析器,也就是说这个解析器需要实现DOM或SAX中定义的接口。提供DOM或SAX中定义的功能。
DOM解析原理
将整棵树一口气全部加载到内存当中, 我们可以非常方便的操作任意的标签和属性.
但是, 如果整棵树特别大的时候, 会出现内存溢出的问题
节点: 标签、属性、文本、甚至是换行都称之为节点
SAX解析原理
一个节点一个节点的进行解析
什么是xml解析器
DOM、SAX都是一组解析XML文档的规范,其实就是接口,这说明需要有实现者能使用,而解析器就是对DOM、SAX的实现了。一般解析器都会实现DOM、SAX两个规范!
Crimson(sun):性能较差
Xerces(IBM):当前最为流行的解析器之一
Aelfred(dom4j):DOM4J默认解析器
jaxp 的方法概述
常用方法:
Document
Element getRootElement():获取根元素对象(跟标签)
Element
List elements(): 获取所有子元素
List elements(string name): 根据指定的元素名称获取相应的所有的子元素
Element element(string name):根据指定的元素名称来获取子对象,如果元素名称重复,则获取第一个元素。
String elementText(string name) : 根据指定的子元素名称,来获取子元素的文本。
String getText():获取当前元素对象的文本。
void setText(string text) :设置当前元素对象的文本。
String attributeValue(String name):根据指定的属性名称 获取对应的值
public Element addAttribute(String name,String value):根据指定的属性名称和值进行添加或者修改BeanUtils的常用方法。
案例演示,增删改查
<!ELEMENT TVSCHEDULE (CHANNEL+)>
<!-- TV.dtd -->
<!ELEMENT CHANNEL (BANNER,DAY+)>
<!ELEMENT BANNER (#PCDATA)>
<!ELEMENT DAY (DATE,(HOLIDAY|PROGRAMSLOT+)+)>
<!ELEMENT HOLIDAY (#PCDATA)>
<!ELEMENT DATE (#PCDATA)>
<!ELEMENT PROGRAMSLOT (TIME,TITLE,DESCRIPTION?)>
<!ELEMENT TIME (#PCDATA)>
<!ELEMENT TITLE (#PCDATA)>
<!ELEMENT DESCRIPTION (#PCDATA)>
<!ATTLIST TVSCHEDULE NAME CDATA #REQUIRED>
<!ATTLIST CHANNEL CHAN CDATA #REQUIRED>
<!ATTLIST PROGRAMSLOT VTR CDATA #IMPLIED>
<!ATTLIST TITLE RATING CDATA #IMPLIED>
<!ATTLIST TITLE LANGUAGE CDATA #IMPLIED>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE TVSCHEDULE SYSTEM "TV.dtd">
<!-- TV.xml-->
<TVSCHEDULE NAME="CCTV">
<CHANNEL CHAN="CCCC">
<BANNER>aaaa</BANNER>
<DAY>
<DATE>2019-1-1</DATE>
<HOLIDAY>xxxxx</HOLIDAY>
</DAY>
<DAY>
<DATE>2019-1-2</DATE>
<PROGRAMSLOT VTR="SSSS">
<TIME>1990</TIME>
<TITLE>test</TITLE>
</PROGRAMSLOT>
</DAY>
</CHANNEL>
</TVSCHEDULE>
<?xml version="1.0" encoding="UTF-8" standalone="no"?><TVSCHEDULE NAME="CCTV">
<!-- TV2.xml-->
<CHANNEL CHAN="CCCC">
<BANNER>aaaa</BANNER>
<DAY>
<DATE>2019-1-1</DATE>
<HOLIDAY>xxxxx</HOLIDAY>
</DAY>
<DAY>
<DATE>2019-1-2</DATE>
<PROGRAMSLOT VTR="SSSS">
<TIME>1990</TIME>
<TITLE>test</TITLE>
</PROGRAMSLOT>
</DAY>
</CHANNEL>
</TVSCHEDULE>
public class Demo01 {
public static void main(String[] args) throws Exception {
Demo01 demo01 = new Demo01();
// demo01.method();
// demo01.method2();
// demo01.add();
// demo01.xiuG();
// demo01.shanC();
// demo01.bianL();
demo01.thisList();
}
public void method() throws Exception {
//创建解析器工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//创建解析器
DocumentBuilder db = dbf.newDocumentBuilder();
//解析xml返回document
Document parse = db.parse("src\\com\\learn_01\\TV.xml");
//得到元素
NodeList list = parse.getElementsByTagName("DATE");
//遍历
for (int i = 0; i < list.getLength(); i++) {
//得到每个DATE标签的元素
Node item = list.item(i);
//得到每个DATE标签的值
String t = item.getTextContent();
System.out.println("取值:" + t);
}
}
public void method2() throws Exception{
//创建解析工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//创建解析器
DocumentBuilder db = dbf.newDocumentBuilder();
//解析xml返回给document
Document parse = db.parse("src\\com\\learn_01\\TV.xml");
//得到元素对应的值
String date = parse.getElementsByTagName("DATE").item(0).getTextContent();
//打印
System.out.println("取值:"+date);
}
public void add() throws Exception{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document parse = db.parse("src\\com\\learn_01\\TV.xml");
NodeList day = parse.getElementsByTagName("DAY");
// 取第一个DAY标签
Node item = day.item(0);
//创建新标签
Element sex = parse.createElement("SEX");
//标签内添加内容
Text boy = parse.createTextNode("男");
// 添加
sex.appendChild(boy);
// 添加
item.appendChild(sex);
//回写xml Transformer 回写类
TransformerFactory tff = TransformerFactory.newInstance();
Transformer tf = tff.newTransformer();
tf.transform(new DOMSource(parse),new StreamResult("src/com/learn_01/TV2.xml"));
}
public void xiuG() throws Exception{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document parse = db.parse("src/com/learn_01/TV2.xml");
//修改元素
parse.getElementsByTagName("SEX").item(0).setTextContent("nan");
TransformerFactory tff = TransformerFactory.newInstance();
Transformer tf = tff.newTransformer();
tf.transform(new DOMSource(parse),new StreamResult("src/com/learn_01/TV2.xml"));
}
public void shanC() throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document parse = db.parse("src/com/learn_01/TV2.xml");
Node sex = parse.getElementsByTagName("SEX").item(0);
Node parentNode = sex.getParentNode();
//删除元素
parentNode.removeChild(sex);
TransformerFactory tff = TransformerFactory.newInstance();
Transformer tf = tff.newTransformer();
tf.transform(new DOMSource(parse),new StreamResult("src/com/learn_01/TV2.xml"));
}
//递归遍历
public void bianL(Node node) {
//判断是元素类型时候才打印
if (node.getNodeType() == Node.ELEMENT_NODE) {
System.out.println(node.getNodeName());
}
//得到一层子节点
NodeList childNodes = node.getChildNodes();
//遍历
for (int i = 0; i < childNodes.getLength(); i++) {
//得到每一个节点
Node item = childNodes.item(i);
// 继续得到item的子节点
// item.getChildNodes();
bianL(item);
}
}
//遍历节点,把所有元素名称打印出来
public void thisList() throws Exception{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document parse = db.parse("src/com/learn_01/TV2.xml");
//编写一个方法实现遍历操作
bianL(parse);
}
}