三十、XML的生成和解析

1.什么是XML?

XML就是可扩展标记语言.HTML是超文本标记语言。


    标记语言就是通过一个一个的标记来组织数据的一种语法格式。
    与HTML超文本标记语言比较的话XML这种可扩展标记语言它的标记是自己定义的。
    XML中自己定义的标记表示:
    例如:  

        <标记名称 属性1=“属性值”属性2=“属性值”....> 具体数据 </标记名称>
        <标记名称>--开始标记
        <标记名称 属性1=“属性值”属性2=“属性值”....>--开始标记
        </标记名称>--结束标记

2.XML的作用是什么?

存储数据的一种语法格式。
    它还可以是一种数据包交换格式。

3.如何编写XML文件?

1).我们现在需要将一个java对象组织成一个xml格式的数据,具体的做法。

1.创建Java类

public  class  Student{
        private  int  stuid;
        private  String  stuname;
        private  int  stuage;
        private  String  stuaddress;
        .....
        getXXX()/setXXX()
}

2)实例化对象

Student  student=new Student();
student.setStuid(1001);
student.setStuname("zhangsan");
student.setStuage(23);
student.setStuaddress("西安");

3)在XML中结构

<?xml version="1.0"  encoding="utf-8"?>
<students>
	<student stuid="1001">
		<stuname>zhangsan</stuname>
		<stuage>23</stuage>
		<stuaddress>西安</stuaddress>				                        
    </student>
</students>

<?xml version="1.0"  encoding="utf-8"?>

xml类型数据/文件的标识
<students>:xml的根元素【必不可少】
<student stuid="1001">:xml的子元素,stuid="1001"就是当前子元素的一个属性
<stuname>zhangsan</stuname>:xml的子子【孙子】元素,zhangsan具体数据值       
注意:

  • <?xml version="1.0"  encoding="utf-8"?>不能少。
  • 根元素只有一个,必不可少。
  • 具体的数据值都是由于子元素/子子【孙子】元素保存。
  • 如果是一个文件,那么文件的后缀名使用“.xml”。
  • 标记都是自己定义,没有固定的具体标记。
  • 子元素、子子元素是可以有多个的。

4.XML文件的生成

java默认的dom生成方式【jdk提供的java类】

  • DOM生成

使用第三方开发包

  • dom4j
  • jdom

原始办法

  • 通过拼接字符串【不推荐,容易出错】

1)DOM生成

public static void productXML(List<Student> stus) throws Exception{
		//得到dom解析器工厂
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		//创建DocumentBuilder对象
		DocumentBuilder documentBuilder = factory.newDocumentBuilder();
		//创建Document对象
		Document dom = documentBuilder.newDocument();
		//设置文档对象的文件头
		dom.setXmlStandalone(true);
		//创建更根元素
		Element root =  dom.createElement("studentlists");
		for (Student stu : stus) {
			//创建子元素
			Element student = dom.createElement("student");
			student.setAttribute("stu_id", String.valueOf(stu.getStuid()));
			//创建子子元素
			Element usedom = dom.createElement("username");
			usedom.setTextContent(stu.getUsername());
			Element passdom = dom.createElement("password");
			passdom.setTextContent(stu.getPasswod());
			Element agedom = dom.createElement("stu-age");
			agedom.setTextContent(stu.getAge()+"");
			Element addressdom = dom.createElement("stu-address");
			addressdom.setTextContent(stu.getAddress());
			student.appendChild(usedom);
			student.appendChild(passdom);
			student.appendChild(agedom);
			student.appendChild(addressdom);
			root.appendChild(student);
		}
		//将根元素添加到Domcument对象中
		dom.appendChild(root);
		//将document对象写出文件
		File xmlfile = new File("studentInfo.xml");
		//创建TransformerFactory对象
		TransformerFactory tff= TransformerFactory.newInstance();
		//创建TransFormer对象
		Transformer tf = tff.newTransformer();
		//输出内容是否使用换行.
		tf.setOutputProperty(OutputKeys.INDENT, "yes");
		tf.transform(new DOMSource(dom), new StreamResult(xmlfile));
	} 

2)dom4j生成

/**
* dom4j
 * 
* */
	public static void dom4jXML(List<Student> stus) throws Exception{
		//闯将DOM对象
		Document dom = DocumentHelper.createDocument();
		//创建根元素
		Element root = dom.addElement("studentlist");
		for (Student stu : stus) {
			Element stuElement = root.addElement("student");
			stuElement.addAttribute("stu-id",String.valueOf( stu.getStuid()));
			Element username = stuElement.addElement("username");
			username.setText(stu.getUsername());
			Element password = stuElement.addElement("password");
			password.setText(stu.getPasswod());
			Element age = stuElement.addElement("stu-age");
			age.setText(String.valueOf(stu.getAge()));
			Element address = stuElement.addElement("stu-address");
			address.setText(stu.getAddress());
		}
		//设置生成xml格式
		OutputFormat format = OutputFormat.createPrettyPrint();
		//设置编码格式
		format.setEncoding("UTF-8");
		//创建xml字符输出流
		XMLWriter writer = new XMLWriter(new FileOutputStream("studentInfo2.xml"),format);
		//设置是否专柜,默认使用转义字符
		writer.setEscapeText(false);
		//洗出DOM对象
		writer.write(dom);
		//关闭流
		writer.close();
	}

3)jdom生成

	public static  void  jdomXML(List<Student> stus) throws Exception {
		Element root = new Element("studnet-list");
		for (Student stu : stus) {
			Element studom = new Element("student");
			studom.setAttribute("stuid", String.valueOf(stu.getStuid()));
			Element username = new Element("username");
			username.setText(stu.getUsername());
			Element password = new Element("password");
			password.setText(stu.getPasswod());
			Element age = new Element("stu-age");
			age.setText(String.valueOf(stu.getAge()));
			Element address = new Element("stu-address");
			address.setText(stu.getAddress());
			studom.addContent(username);
			studom.addContent(password);
			studom.addContent(age);
			studom.addContent(address);
			root.addContent(studom);
		}
		
		Document  document=new Document(root);
		//输出dom对象
		Format format = Format.getCompactFormat();
		//设置换行tab或空格
		format.setIndent("\t");
		format.setEncoding("UTF-8");
		//创建XMLOutputter对象
		XMLOutputter outputer = new XMLOutputter(format);
		//写出dom对象
		outputer.output(document, new FileOutputStream("studentinfo3.xml"));
		
	}

5.XML文件的解析

JDK提供的

  • DOM(Document Object Model)解析

第三方的

  • dom4j
  • jdom
  • SAX(Simple API for XML)解析

1)DOM解析

public class ReadXML {
	public static List<Student> jdkdomgetxml() throws Exception{
		List<Student>list = new ArrayList<Student>();
		//得到解析器工厂
		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
		//得到解析器对象
		DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
		//创建dom对象
		org.w3c.dom.Document dom = documentBuilder.parse(new File("studentInfo.xml"));
		//得到所有的子元素集合
		NodeList stunodelist = dom.getElementsByTagName("student");
		for (int i = 0; i < stunodelist.getLength(); i++) {
			Student student = new Student();
			Node stuelement = stunodelist.item(i);
			int stuid = Integer.parseInt(stuelement.getAttributes().item(0).getNodeValue());
			student.setStuid(stuid);
			NodeList studentinfos = stuelement.getChildNodes();
			for (int j = 1; j < studentinfos.getLength(); j++) {
				Node atElement = studentinfos.item(j);
				String nameElement = atElement.getNodeName();
				System.out.println(nameElement);
				String info = atElement.getTextContent();
				if (nameElement.equals("username")) {
						student.setUsername(info);
				}
				if (nameElement.equals("password")) {
					student.setPasswod(info);
				}
				if (nameElement.equals("stu-age")) {
					student.setAge(Integer.parseInt(info));
				}
				if (nameElement.equals("stu-address")) {
					student.setAddress(info);
				}
			}
			list.add(student);
		}
		return list;
	}

2)dom4j解析

/**
	 * dom4j
	 * @return List<Student>
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static List<Student> dom4jgetxml(String filename) throws Exception{
		List<Student> stuinfo = new ArrayList<Student>();
		SAXReader saxRead = new SAXReader();
		Document dom = saxRead.read(new File(filename));
		Element rootele = dom.getRootElement();
		List<Element> studentElementlist = rootele.elements("student");
		for (Element studentele : studentElementlist) {
			Student student = new Student();
			int stuid = Integer.parseInt(studentele.attributeValue("stu-id"));
			Element usernameele = studentele.element("username");
			String username = usernameele.getText();
			Element passwordele = studentele.element("password");
			String password = passwordele.getText();
			Element ageele = studentele.element("stu-age");
			int age = Integer.parseInt(ageele.getText());
			Element addressele = studentele.element("stu-address");
			String address = addressele.getText();
			student.setStuid(stuid);
			student.setUsername(username);
			student.setPasswod(password);
			student.setAge(age);
			student.setAddress(address);
			stuinfo.add(student);
		}
		return stuinfo;
	}

3)Jdom解析

/***
	 * 
	 * @param filename
	 * @return
	 * @throws Exception
	 */
	public static List<Student> jdomXML (String filename) throws Exception{
		List<Student> stuinfo = new ArrayList<Student>();
			SAXBuilder aSaxBuilder = new SAXBuilder();
			Document dom = aSaxBuilder.build(new File(filename));
			Element root = dom.getRootElement();
			List<Element> studentdom = root.getChildren("student");
			for (Element element : studentdom) {
				int stuid=Integer.parseInt(element.getAttributeValue("stuid"));
				Element stunamedom = element.getChild("username");
				String username = stunamedom.getText();
				Element stupassworddom = element.getChild("password");
				String password = stupassworddom.getText();
				Element agedom = element.getChild("stu-age");
				int age =Integer.parseInt(agedom.getText()) ;
				Element stuaddressdom = element.getChild("stu-address");
				String address = stuaddressdom.getText();
				Student  stu = new Student(stuid, username, password, age, address);
				stuinfo.add(stu);
			}
		return stuinfo;
	}

DOM解析的原理:

就是需要被解析的xml文件,读取成一个文档树【Document 对象】,依据提供的开发类库和方法从文档树中得到根元素,再从根元素中得到子元素,从子元素中的到子子元素,再得到具体的数据值。
    优点:结构清晰明了。
    缺点:通常需要加载整个XML文档来构造层次结构,消耗资源大.

4)SAX解析

需要借助:DefaultHandler.

解析xml文件的原理:

基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的标签的时候,它可以激活一个回调方法,告诉该方法指定的标签已经找到,如果这个指定的标记中中有我们需要数据值就解析,没有就不用处理。读取一个元素,判断这一个元素属于xml文件的哪一个元素【文档开始/文档结束/标记开始/标记结束/文本元素】,不同的元素触发不同的方法来执行解析数据,如果当前元素中没有数据值就跳过读取下一个元素。

(1)声明解析方法

public static List<Student> getXMLsax (String filename) throws Exception{j
        //得到SAX解析工厂
        SAXParserFactory saxfac= SAXParserFactory.newInstance();
        //从工厂中得到解析器对象
        SAXParser saxParser = saxfac.newSAXParser();
        MyDefaultHandle myDefualtHandle= new MyDefaultHandle();
        saxParser.parse(new File(filename), myDefualtHandle);
        return myDefualtHandle.getStudent();
        
}

(2) 需要继承DefaultHandler来实现读取获取元素、文档、数据的方法

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class MyDefaultHandle extends DefaultHandler{
	private List<Student> studentlist = null;
	private Student student = null;
	private String eleName = "";
	/**
	 * 得到解析后的数据集合
	 * @return
	 */
	public List<Student> getStudent() {
		return studentlist;
	}
	/***
	 * 文档的开始
	 */
	@Override
	public void startDocument() throws SAXException {
		studentlist = new ArrayList<Student>();
	}
	/**
	 * 文档结束
	 */

	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.endDocument();
	}
	/**
	 * 元素开始
	 */
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		if (qName.equals("student")) {
			student = new Student();
			int stuid = Integer.parseInt(attributes.getValue("stuid"));
			student.setStuid(stuid);
		}
		if (qName.equals("username")) {
			eleName = qName;
		}
		if (qName.equals("password")) {
			eleName = qName;
		}
		if (qName.equals("stu-age")) {
			eleName = qName;
		}
		if (qName.equals("stu-address")) {
			eleName = qName;
		}
	}
	/**
	 * 元素结束
	 */
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		eleName = "";
		if (qName.equals("student")) {
			studentlist.add(student);
			student = null;
		}
	}
	/**
	 * 得到数据
	 */
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		String info = new String(ch, start,length);
		if (eleName.equals("username")) {
			student.setUsername(info);
		}
		if (eleName.equals("password")) {
			student.setPasswod(info);
		}
		if (eleName.equals("stu-age")) {
			student.setAge(Integer.parseInt(info));
		}
		if (eleName.equals("stu-address")) {
			student.setAddress(info);
		}
	}

}

优点:1.只在读取数据时检查数据,不需要保存在内存中 
         2.可以在某个条件得到满足时停止解析,不必解析整个文档。
         3.效率和性能较高,能解析大于系统内存的文档。
缺点:没有清晰的解析结构。

无奈源于不够强大

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值