什么是 XML
-
XML
(Extensible Markup Language)是一种可扩展标记语言 - 语法简单,灵活性高,扩展性强
- XML 文档的使用与操作系统、编程语言的开发平台无关
- XML 的本质就是一个特殊格式的文本文档
XML 的作用
- 数据存储
- 配置文件
- 数据交换
XML 的文档结构
声明部分
<?xml version="1.0" encoding="UTF-8"?>
-
<?xml
:声明的开头 -
?>
:声明的结尾 -
version="1.0"
:表示该 xml 文档符合 1.0 的规范 -
encoding="UTF-8"
:表示该 xml 文档的编码模式为 UTF-8
内容部分
节点
-
xml 的内容部分主要由各种节点组成,节点又分为
标签节点
、注释节点
、文本节点
等 -
每个 xml 文档必须有且有一个
根标签节点
标签节点
开放式标签
开放式标签由 <...>
和 结束标签</...>
构成
<PhoneInfo></PhoneInfo>
-
<PhoneInfo>
:起始标签 -
</PhoneInfo>
:结束标签
自闭合标签
自闭合标签没有 结束标签
,它是由 <
和 />
构成
<Type name="P9"/>
标签属性
<Brand name="华为">
<Type name="P9"/>
</Brand>
-
name="华为"
:属性,多个属性之间应该用空格隔开 -
name
:属性名 -
"华为"
:属性值,属性值应该用""
或''
包裹
注释
xml 中的注释是由 <!--
开始 和 -->
结束,中间的部分为注释内容
<!-- 手机列表 -->
文本节点
写在开放标签内部的文本内容即为 文本节点
<Type>P9</Type>
特殊字符处理
使用实体名称处理
<author>李明明 & 王珊</author>
特殊字符 | 实体名 |
---|---|
< |
< |
> |
> |
" |
" |
' |
' |
& |
& |
使用 CDATA 节处理
<author><![CDATA[李明明 & 王珊]]></author>
XML 文档解析
使用 DOM 解析
读取 XML 文档
//获取解析器工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//获取解析器
DocumentBuilder builder = factory.newDocumentBuilder();
//获取DOM树
Document doc = builder.parse("收藏信息.xml");
获取节点对象
获取根节点
Element root = doc.getDocumentElement();
根据ID值获取节点
<Brand id="1">...</Brand>
Element ele = doc.getElementById("1");
根据标签名称获取节点
<Brand name="华为">...</Brand>
NodeList nodes = doc.getElementsByTagName("Brand");
根据标签名获取当前节点下的子节点
<PhoneInfo>
<Brand name="华为">...</Brand>
<Brand name="苹果">...</Brand>
</PhoneInfo>
Element root = doc.getDocumentElement();
NodeList nodes = root.getElementsByTagName("Brand");
获取所有子节点
Element root = doc.getDocumentElement();
NodeList nodes = root.getChildNodes();
获取第一个子元素
Element root = doc.getDocumentElement();
Node firstNode = root.getFirstChild();
获取最后一个子元素
Element root = doc.getDocumentElement();
Node lastNode = root.getLastChild();
获取下一个同级元素
Element root = doc.getDocumentElement();
Node firstNode = root.getFirstChild();
Node nextNode = firstNode.getNextSibling();
获取上一个同级元素
Element root = doc.getDocumentElement();
Node lastNode = root.getLastChild();
Node preNode = lastNode.getPreviousSibling();
获取指定索引的节点
Element root = doc.getDocumentElement();
NodeList nodes = root.getChildNodes();
Node node = nodes.item(0);
获取父级节点
NodeList brands = doc.getElementsByTagName("Brand");
Node brand = brands.item(0);
Element brandEle = (Element)brand;
Node parentNode = brandEle.getParentNode();
获取节点信息
获取节点列表的长度
Element root = doc.getDocumentElement();
NodeList nodes = root.getChildNodes();
int leg = nodes.getLength();
获取节点的标签名
通过Element对象获取
Element root = doc.getDocumentElement();
Node firstNode = root.getFirstChild();
Element ele = (Element)firstNode;
String tagName = ele.getTagName();
通过Node对象获取
Element root = doc.getDocumentElement();
Node firstNode = root.getFirstChild();
String tagName = firstNode.getNodeName();
获取节点类型
Element root = doc.getDocumentElement();
Node node = root.getFirstChild();
short type = node.getNodeType();
if(type==Node.ELEMENT_NODE){
System.out.println("标签节点");
}else if(type==Node.TEXT_NODE){
System.out.println("文本节点");
}else if(type==Node.ATTRIBUTE_NODE){
System.out.println("属性节点");
}else if(type==Node.COMMENT_NODE){
System.out.println("注释节点");
}
获取文本节点的值
如果尝试获取非文本节点的值,则返回 null
Element root = doc.getDocumentElement();
Node firstNode = root.getFirstChild();
if(firstNode.getNodeType()==Node.TEXT_NODE){
System.out.println(firstNode.getNodeValue());
}
操作节点
创建节点
Element ele = doc.createElement("Brand");
追加子节点
Element root = doc.getDocumentElement();
Element ele = doc.createElement("Brand");
root.appendChild(ele);
删除子节点
元素节点无法自己删除自己,只能先找到父级元素,然后由父级元素将自己删除
NodeList brands = doc.getElementsByTagName("Brand");
Node brand = brands.item(0);
Element brandEle = (Element)brand;
brandEle.getParentNode().removeChild(brandEle);
节点属性操作
获取指定属性的值
Element root = doc.getDocumentElement();
Node node = root.getFirstChild();
Element ele = (Element)node;
String attr = ele.getAttribute("name");
修改指定属性的值
NodeList brands = doc.getElementsByTagName("Brand");
for(int i=0;i<brands.getLength();i++){
Node brand = brands.item(i);
Element brandEle = (Element)brand;
if(brandEle.getAttribute("name").equals("三星")){
brandEle.setAttribute("name", "SAMSUNG");
}
}
新增属性
Element ele = doc.createElement("Brand");
ele.setAttribute("name", "三星");
移除属性
Element root = doc.getDocumentElement();
Node node = root.getFirstChild();
Element ele = (Element)node;
ele.removeAttribute("name");
保存 XML 文档
//创建转换工厂
TransformerFactory factory = TransformerFactory.newInstance();
//创建转换器
Transformer former = factory.newTransformer();
//创建DOM源
DOMSource xmlSource = new DOMSource(doc);
//创建XML文档流
StreamResult outputTarget = new StreamResult(new FileOutputStream("新的收藏信息.xml"));
//设置编码
former.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
//把DOM树转换为XML文件
former.transform(xmlSource, outputTarget);
使用 DOM4J 解析
导入依赖包
读取 XML 文档
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read("收藏信息.xml");
获取节点对象
获取根节点
Element root = doc.getRootElement();
获取指定节点名的子节点,只返回第一个匹配的子节点
Element root = doc.getRootElement();
Element ele = root.element("member");
获取指定节点名的子节点,返回所有匹配的子节点
Element root = doc.getRootElement();
List eles = root.elements("member");
获取所有的子节点
Element root = doc.getRootElement();
List eles = root.elements();
获取子节点迭代器
Element root = doc.getRootElement();
Iterator iterator =root.elementIterator();
while(iterator.hasNext()){
Element ele = (Element)iterator.next();
}
获取指定节点名的子节点迭代器
Element root = doc.getRootElement();
Iterator iterator =root.elementIterator("Brand");
while(iterator.hasNext()){
Element ele = (Element)iterator.next();
}
获取指定ID的子元素
Element root = doc.getRootElement();
Element ele = root.elementByID("1");
获取父级元素
Element root = doc.getRootElement();
Element ele = root.element("member");
Element parentEle = ele.getParent();
获取节点信息
获取当前节点中的文本
Element root = doc.getRootElement();
Element ele = root.element("member");
String text = ele.getText();
获取根节点下指定子节点中的文本
Element root = doc.getRootElement();
String text = root.elementText("name");
操作节点
创建并追加节点
Element root = doc.getRootElement();
Element brandEle = root.addElement("Brand");
删除节点
Element root = doc.getRootElement();
Element ele = root.element("member");
ele.getParent().remove(ele);
设置文本
Element root = doc.getRootElement();
Element ele = root.element("name");
ele.setText("张三");
节点属性操作
获取属性的值
Element root = doc.getRootElement();
Element brandEle = root.addElement("Brand");
String brandStr = brandEle.attributeValue("name");
修改属性的值
Element root = doc.getRootElement();
Element brandEle = root.addElement("Brand");
brandEle.addAttribute("name","小米");
添加属性
Element root = doc.getRootElement();
Element brandEle = root.addElement("Brand");
brandEle.addAttribute("price","4000");
获取指定名称的属性对象
Element root = doc.getRootElement();
Element brandEle = root.addElement("Brand");
Attribute attr = brandEle.attribute("name");
移除属性
Element root = doc.getRootElement();
Element brandEle = root.addElement("Brand");
Attribute attr = brandEle.attribute("name");
brandEle.remove(attr);
保存 XML 文档
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileWriter(path),format);
writer.write(doc);
writer.close();