XML不多总结,值得一提的是,XML中对特殊字符的处理。
如果在XML中有大量的特殊字符,可以使用CDATA处理。
CDATA中的所有字节都会被当做字符数据的常量部分。
语法:<![CDATA[ ]]>
XML注释语法:<!-----注释内容------>
重点是解析XML。这里总结两种方式。
DOM解析方式:
DOM是 基于XML的数结构来完成解析的。DOM解析文档时,会根据读取的文档,构建一个驻留内存的树结构,然后使用DOM接口来操作这个树结构。因为整个DOM数是驻留在内存中的,所以进行各种访问操作时非常方便。DOM解析的方式非常适用于多次访问XML的程序,但是DOM解析是比较消耗资源的。
<?xml version="1.0" encoding="GB2312"?>
<PhoneInfo>
<Brand name="华为">
<Type name="P9" />
</Brand>
<Brand name="苹果">
<Type name="iphone6" />
<Type name="iphone7" />
</Brand>
</PhoneInfo>
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DOMParseDemo {
// 创建全局Document文档对象
Document doc = null;
/*
* 加载xml文件到内存中
*/
public void loadDocument() {
try {
// 得到DOM解析器的工厂实例
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 从DOM工厂获得DOM解析器
DocumentBuilder db = dbf.newDocumentBuilder();
// 利用DOM解析器解析到内存中
doc = db.parse("收藏信息.xml");
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
}
/*
* 显示所有的Brand
*/
public void showInfo() {
// 要显示所有的Brand首先要得到所有的Brand节点列表信息
NodeList brandList = doc.getElementsByTagName("Brand");
// 首先循环Brand信息
for (int i = 0; i < brandList.getLength(); i++) {
// 获取每个Brand节点的信息
Node brand = brandList.item(i);
// 获取每个Brand节点的name元素的值
Element element = (Element) brand;
String attrValue = element.getAttribute("name");
// 获取每个Brand元素的所有子元素
// 首先先获取每个Brand元素的所有子元素
NodeList types = element.getChildNodes();
// 循环每个子元素输出每个子元素的name属性值
for (int j = 0; j < types.getLength(); j++) {
Node typeNode = types.item(j);
// 遍历时会有空格。如果当前Node是一个Element,才进行转换
if (typeNode.getNodeType() == Node.ELEMENT_NODE) {
Element typeElement = (Element) typeNode;
// 获取此ElementName属性
String typeStr = typeElement.getAttribute("name");
System.out.println("手机:" + attrValue + ",型号" + typeStr);
}
}
}
}
/*
* 保存XML文件
*/
public void saveXML(String path) {
try {
// 用转换工厂创建转换对象
TransformerFactory factory = TransformerFactory.newInstance();
Transformer newTransformer = factory.newTransformer();
// 创建资源文档
DOMSource domSource = new DOMSource(doc);
// 设置编码格式
newTransformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
StreamResult result = new StreamResult(path);
// 把DOM数转化为XML文件
newTransformer.transform(domSource, result);
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
/*
* 增加节点信息操作
*/
public void addNewPhoneInfo(){
//创建Brand节点
Element brandElement = doc.createElement("Brand");
//设置节点信息
brandElement.setAttribute("name", "三星");
//创建子节点
Element typeElement=doc.createElement("Type");
typeElement.setAttribute("name", "Node8");
//最后添加父子关系,先从底层添加父子关系,把Type挂到Brand上
brandElement.appendChild(typeElement);
//最后挂到最高节点PhoneInfo上,首先得获取PhoneInfo节点,然后获取第一个节点(下标为0),然后加上子节点
doc.getElementsByTagName("PhoneInfo").item(0).appendChild(brandElement);
}
/*
* 更新节点信息操作
* 把name为三星的Brand改为SAMSUNG
*/
public void modifyPhoneInfo() {
// 先获取所有Brand的节点列表
NodeList list = doc.getElementsByTagName("Brand");
// 循环Brand的list列表
for (int i = 0; i < list.getLength(); i++) {
//获取每个元素
Node brandNode = list.item(i);
Element ele = (Element) brandNode;
// 获取每个元素的第一个属性name的值
String brandName = ele.getAttribute("name");
// 判断操作,如果name的值为三星,就设置为SAMSUNG
if (brandName.equals("三星")) {
ele.setAttribute("name", "SAMSUNG");
}
}
}
/*
* 删除节点操作
* 删除SANSUNG
*/
public void delPhoneInfo(){
//先获取所有的Brand列表
NodeList list = doc.getElementsByTagName("Brand");
//循环Brand的list列表
for(int i=0;i<list.getLength();i++){
Element ele = (Element) list.item(i);
// 获取每个元素的第一个属性name的值
String attribute = ele.getAttribute("name");
if(attribute.equals("SAMSUNG")){
//要通过父节点来删除子节点
ele.getParentNode().removeChild(ele);
}
}
}
public static void main(String[] args) {
DOMParseDemo dom = new DOMParseDemo();
dom.loadDocument();
dom.addNewPhoneInfo();
dom.modifyPhoneInfo();
dom.delPhoneInfo();
dom.saveXML("练习的收藏信息.xml");
dom.showInfo();
}
}
DOM4J解析方式:
DOM4J是一种非常优秀的JAVA XML API,具有卓越的性能。功能强大并且易用。
同时也是开源的软件。如今越来越多的java软件都在使用DOM4J来读写XML。
Sun公司的JAVAXM也在使用DOM4J。
<?xml version="1.0" encoding="GB2312"?>
<PhoneInfo>
<Brand name="华为">
<Type name="P9" />
</Brand>
<Brand name="苹果">
<Type name="iphone6" />
<Type name="iphone7" />
</Brand>
</PhoneInfo>
/*
* 使用DOM4J解析XML文件
*/
public class DOM4JXMLParse {
Document doc=null;
/*
* 加载xml文件的方法
*/
public void loadDocument(){
try {
//加载xml文件到内存中来
SAXReader saxReader=new SAXReader();
doc = saxReader.read("收藏信息.xml");
} catch (DocumentException e) {
e.printStackTrace();
}
}
/*
* 保存XML
*/
public void saveXML(String path){
//创建一个pretty的格式化器
OutputFormat format=OutputFormat.createPrettyPrint();
//写文件操作
try {
XMLWriter writer=new XMLWriter(new FileWriter(path), format);
//写入文档对象
writer.write(doc);
//及时关闭写入流操作
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/*
* 显示DOM信息
*/
public void showInfo(){
//得到整个DOM数的根节点
Element root = doc.getRootElement();
//得到根节点的子节点集合
Iterator iterator = root.elementIterator();
//遍历集合
while(iterator.hasNext()){
Element brandEle = (Element) iterator.next();
//获取第一层的name属性的值
String brandStr = brandEle.attributeValue("name");
//获取第一层节点的下一层的节点值,DOM4J中已经做了判断,不需判断是否为Element对象
Iterator itType = brandEle.elementIterator();
//循环第一层的所有子节点
while(itType.hasNext()){
Element typeEle=(Element) itType.next();
String typeStr = typeEle.attributeValue("name");
System.out.println("手机:"+brandStr+",型号:"+typeStr);
}
}
}
/*
* 新增节点
* (三星 S8)
*/
public void addPhoneInfo(){
//首先拿到根节点
Element root= doc.getRootElement();
//在根节点下创建子节点
Element brandElement = root.addElement("Brand");
//给子节点设置属性
brandElement.addAttribute("name", "三星 ");
//给子节点创建下一个子节点
Element typeElement=brandElement.addElement("Type");
//设置属性
typeElement.addAttribute("name", "Note8");
}
/*
* 修改节点信息
* 为每一个节点添加一个id信息
*/
public void modifyPhoneInfo(){
//首先拿到根节点
Element root = doc.getRootElement();
//定义计数器
int id=0;
//获取所有节点的iterator。
Iterator itBrand = root.elementIterator();
//遍历获取每个brand
while(itBrand.hasNext()){
id++;
//遍历下一个
Element brandele=(Element) itBrand.next();
//为每个节点增加id属性
brandele.addAttribute("id", id+"");
}
}
/*
* 删除节点操作
* 删除节点三星
*/
public void delPhoneInfo(){
//首先获取根节点
Element root = doc.getRootElement();
//得到所有的子节点
Iterator itBrand = root.elementIterator();
while(itBrand.hasNext()){
Element ele=(Element) itBrand.next();
if(ele.attributeValue("name").equals("三星")){
//若找到name的值为三星的节点,则由此节点的父节点来移除此节点
ele.getParent().remove(ele);
}
}
}
public static void main(String[] args) {
DOM4JXMLParse dom4j=new DOM4JXMLParse();
dom4j.loadDocument();
dom4j.modifyPhoneInfo();
dom4j.showInfo();
}
}