XML(EXtensible Markup Language)

  • Post author:
  • Post category:其他


一、XML 基础

XML(EXtensible Markup Language),全称可扩展标记语言,可以实现不同系统之间的数据交换,与操作系统、编程语言的开发平台无关

作用:数据交互;配置应用程序和网站;Ajax基石

XML 编写注意事项:

  1. 所有 XML 元素都必须要有结束标签
  2. XML 标签对大小写敏感
  3. XML 必须正确嵌套,同级标签以缩进对齐
  4. 元素名称可以包含字母、数字或其他字符
  5. 元素名称不能以数字或标点符号开头
  6. 元素名称中不能有空格
  7. 一个元素可以有多个属性
  8. 属性值用双引号包裹,属性值中不能直接包含

    <







    &

    ,不建议包含





    >

XML 文档示例:

上图对应 XML 文档:

<?xml version="1.0" encoding="UTF-8"?>
<clothes>
	<clothe size="S" height="身高&lt;165"></clothe>
	<clothe size="M" height="165&lt;身高&lt;175"></clothe>
	<clothe size="L" height="175&lt;身高&lt;185"></clothe>
</clothes>

XML 命名空间:解决在复杂、大型XML文件中,出现名称相同,但是含义不同的元素

属性命名空间:除非带有前缀,否则属性属于所属的元素的命名空间

XML 解析器:——————回头记得补充!

  1. 非验证解析器:检查文档格式是否良好
  2. 验证解析器:使用DTD检查文档的有效性

解析 XML 技术:

  1. DOM

    基于XML文档树结构的解析;适用于多次访问的XML文档;特点:比较消耗资源
  2. SAX

    基于事件的解析;适用于大数据量的XML文档;特点:占用资源少,内存消耗小
  3. DOM4J

    非常优秀的Java XML API;性能优异、功能强大;开放源代码

二、DOM 解析 XML

使用 DOM 解析增删改查的示例:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
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 ParseDom {
	//document对象:将整个dom文档解析成的对象,该对象可以处理xml的增删改查功能
	private Document dom = null;
	
	//获取document对象
	public void getDom(String path) {
		//dom解析工厂来创建dom对象
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		//由工厂创建解析器:该解析器可以将xml文件构造成document对象
		try {
			DocumentBuilder builder = factory.newDocumentBuilder();
			//解析文档创建dom
			dom = builder.parse(path);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//打印手机信息:先打印品牌,再遍历型号
	public void getInfo(String path) {
		getDom(path);
		//获取标签brand的节点对象集合
		NodeList brands = dom.getElementsByTagName("Brand");
		for(int i = 0;i < brands.getLength();i++) {
			Node brandNode = brands.item(i);
			//获取品牌节点里面的属性
			Element brandElement = (Element) brandNode;
			String brandName = brandElement.getAttribute("name");
			System.out.println(brandName);
			//需要获取每个品牌里面的子元素型号,遍历打印型号
			NodeList types = brandElement.getChildNodes();
			for(int j = 0;j < types.getLength();j++) {
				Node typeNode = types.item(j);
				//判断是元素标签才能转换
//				if(typeNode instanceof Element) {
				if(typeNode.getNodeType() == Node.ELEMENT_NODE) {
					Element typeElement = (Element) typeNode;
					String typeName = typeElement.getAttribute("name");
					System.out.println("\t"+typeName);
				}
			}
		}
	}
	
	//添加节点:添加 三星 Note4 手机
	public void addEle(String path,String brand,String type) {
		getDom(path);
		//创建品牌节点和属性
		Element brandElement = dom.createElement("Brand");
		brandElement.setAttribute("name", brand);
		//创建型号节点和属性
		Element typeElement = dom.createElement("Type");
		typeElement.setAttribute("name", type);
		//追加到相应的位置
		brandElement.appendChild(typeElement);
		dom.getElementsByTagName("PhoneInfo").item(0).appendChild(brandElement);
		//保存到文件
		saveXML(path);
	}
	
	//保存到文件 需要传输器将dom对象保存到指定文件中
	public void saveXML(String path) {
		//创建传输器工厂
		TransformerFactory factory = TransformerFactory.newInstance();
		//由工厂创建传输器
		try {
			Transformer transformer = factory.newTransformer();
			//传输
			DOMSource source = new DOMSource(dom);
			//设置编码方式
			transformer.setOutputProperty("encoding", "UTF-8");
			StreamResult result = new StreamResult(new File(path));
			transformer.transform(source, result);
		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		}
	}
	
	//删除:根据标签名name属性删除元素,例如删除 苹果
	public void deleteEle(String path,String delbrand) {
		getDom(path);
		NodeList brands = dom.getElementsByTagName("Brand");
		for(int i = 0;i < brands.getLength();i++) {
			Node brandNode = brands.item(i);
			//获取品牌节点里面的属性
			Element brandElement = (Element) brandNode;
			String brandName = brandElement.getAttribute("name");
			if(brandName.equals(delbrand)) {
				brandElement.getParentNode().removeChild(brandElement);
//					break;
			}
		}
		saveXML(path);
	}
	
	public void change(String path,String oldbrand,String brand,String type) {
		getDom(path);
		Element newbrand = dom.createElement("Brand");
		newbrand.setAttribute("name", brand);
		Element newtype = dom.createElement("Type");
		newtype.setAttribute("name", type);
		newbrand.appendChild(newtype);
		NodeList brands = dom.getElementsByTagName("Brand");
		for(int i = 0;i < brands.getLength();i++) {
			Node brandNode = brands.item(i);
			//获取品牌节点里面的属性
			Element brandElement = (Element) brandNode;
			String brandName = brandElement.getAttribute("name");
			if(brandName.equals(oldbrand)) {
				brandElement.getParentNode().replaceChild(newbrand, brandElement);
			}
		}
		saveXML(path);
	}
	
	public void change(String path,String label,String attrname,String oldattr,String newattr) {
		getDom(path);
		NodeList labels = dom.getElementsByTagName(label);
		for(int i = 0;i < labels.getLength();i++) {
			Node labelNode = labels.item(i);
			//获取节点里面的属性
			Element element = (Element) labelNode;
			String attrValue = element.getAttribute(attrname);
			if(attrValue.equals(oldattr)) {
				element.setAttribute(attrname, newattr);
			}
		}
		saveXML(path);
	}
	
	public static void main(String[] args) {
		ParseDom parseDom = new ParseDom();
//		parseDom.getDom("收藏信息.xml");
//		System.out.println(parseDom.dom);
		parseDom.addEle("收藏信息.xml","三星", "Note4");
		//parseDom.deleteEle("收藏信息.xml", "oppo");
		//parseDom.change("收藏信息.xml", "三星", "小米", "10");
		//parseDom.change("收藏信息.xml", "Brand", "name", "三星", "华为");
		//parseDom.change("收藏信息.xml", "Type", "name", "Note4", "MaxPro");
		parseDom.getInfo("收藏信息.xml");
	}
}

三、DOM4J 解析 XML

eclipse 使用 DOM4J 记得导入jar包:这里用的是 dom4j-1.6.1.jar

使用 DOM4J 解析增删改查的示例:

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ParseDom4J {
	private Document dom = null;
	
	//获取document对象
	public void getDom(String path) {
		SAXReader reader = new SAXReader();
		try {
			dom = reader.read(path);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
	
	//读取文件信息
	public void getInfo(String path) {
		getDom(path);
		//获取根节点
		Element root = dom.getRootElement();
		//获取brand节点的集合
		Iterator<Element> brandsIt = root.elementIterator("Brand");
		//用迭代器遍历brand
		while(brandsIt.hasNext()) {
			Element brand = brandsIt.next();
			//打印name属性值
			String brandName = brand.attributeValue("name");
			System.out.println(brandName);
			//打印型号
			Iterator<Element> typeIt = brand.elementIterator("Type");
			while(typeIt.hasNext()) {
				Element type = typeIt.next();
				String typeName = type.attributeValue("name");
				System.out.println("\t"+typeName);
			}
		}
	}
	
	//添加节点:添加 小米 10 手机
	public void addEle(String path,String brand,String type) {
		getDom(path);
		Element root = dom.getRootElement();
		//创建品牌节点和属性,添加到根节点下面
		Element brandElement = root.addElement("Brand");
		brandElement.addAttribute("name", brand);
		//创建型号节点和属性,添加到品牌节点下面
		brandElement.addElement("Type").addAttribute("name", type);
		//保存到文件
		saveXML(path);
	}
	
	//保存到xml文件
	public void saveXML(String path) {
		XMLWriter writer;
		try {
			writer = new XMLWriter(new FileOutputStream(path));
			writer.write(dom);
			writer.flush();
			writer.close();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	//删除:根据标签名name属性删除元素,例如删除 三星
	public void deleteEle(String path,String delbrand) {
		getDom(path);
		Element root = dom.getRootElement();
		Iterator<Element> brandIt = root.elementIterator("Brand");
		while(brandIt.hasNext()) {
			Element brand = brandIt.next();
			if(brand.attributeValue("name").equals(delbrand)) {
				brand.getParent().remove(brand);
//				break;
			}
		}
		saveXML(path);
	}
	
	public void change(String path,String oldbrand,String oldtype,String newbrand,String newtype) {
		getDom(path);
		Element root = dom.getRootElement();
		Iterator<Element> brandIt = root.elementIterator("Brand");
		while(brandIt.hasNext()) {
			Element brand = brandIt.next();
			if(brand.attributeValue("name").equals(oldbrand)) {
				brand.setAttributeValue("name", newbrand);
				Iterator<Element> typeIt = brand.elementIterator("Type");
				while(typeIt.hasNext()) {
					Element type = typeIt.next();
					if(type.attributeValue("name").equals(oldtype)) {
						type.attribute("name").setValue(newtype);
					}
				}
			}
		}
		saveXML(path);
	}
	
	public static void main(String[] args) {
		ParseDom4J parseDom4J = new ParseDom4J();
//		parseDom4J.getDom("收藏信息.xml");
//		System.out.println(parseDom4J.dom);
		parseDom4J.addEle("收藏信息.xml", "小米", "10");
        //parseDom4J.deleteEle("收藏信息.xml", "三星");
		//parseDom4J.change("收藏信息.xml", "三星", "Galaxy", "oppo", "R5");
		parseDom4J.getInfo("收藏信息.xml");
	}
}

附:收藏信息(可能有点格式问题)及其文件位置

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PhoneInfo>
	<Brand name="华为">
		<Type name="U8650"/>
		<Type name="HW123"/>
		<Type name="HW321"/>
	</Brand>

    <Brand name="荣耀"><Type name="p30"/></Brand><Brand name="oppo"><Type name="R5"/></Brand>
    <Brand name="小米"><Type name="10"/></Brand>
</PhoneInfo>

(是直接放在 src 文件夹下的:src > 收藏信息.xml)



版权声明:本文为wzskqfzl_zg原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。