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.效率和性能较高,能解析大于系统内存的文档。
缺点:没有清晰的解析结构。
无奈源于不够强大