我爱编程

XML*

2018-01-06  本文已影响0人  望町

目录


XML简介

XML(Extend Markup Language)是一种标记语言,被用来格式化的传输数据
示例

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type = "text/css">
<!--this is content-->
<CATALOG>
  <CD id = "132">
    <TITLE>Empire Burlesque</TITLE>
    <ARTIST>Bob Dylan</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>Columbia</COMPANY>
    <PRICE>10.90</PRICE>
    <YEAR>1985</YEAR>
  </CD>
</CATALOG>

其中:


XML基本语法

一、XML对大小写敏感
二、所有XML标签都必须有关闭标签
三、头尾标签名应该一样
四、属性值必须加引号
五、在 XML 中,空格会被保留(XML中多个空格只会保留一个)
六、实体引用(转义字符)

<![CDATA[<html><head></head><body></body></html>]]>

DOM解析

1)DOM解析原理
DOM解析XML文档时,XML解析器一次性吧整个XML文档加载进内存,然后在内存中构建一棵Document对象树,通过Document对象,可以得到下面的节点对象,通过节点对象访问数据
2)DOM解析工具

DOM4J解析工具

需要导包使用

1)dom4j结构


domj4.png

2)dom4j读取xml文件
节点:

标签:

属性:

文本:

示例1:利用dom4j输出一个xml文件

public class Demo1 {
    @Test
    public void test()throws Exception {
        SAXReader  reader = new SAXReader();
        Document document = reader.read(new File("./src/contact.xml"));
        //获得根标签
        Element element = document.getRootElement();
        StringBuffer sb = new StringBuffer();
        //用此方法遍历整个xml文件(先根遍历形式)
        getchild(element,sb);
        System.out.println(sb.toString());
        }

    private void getchild(Element element, StringBuffer sb) {
        // TODO Auto-generated method stub
        sb.append("<"+element.getName());
        //获得标签的所有属性
        List<Attribute> attrs = element.attributes();
        //输出标签属性
        if(attrs!=null) {
            for (Attribute attribute : attrs) {
                sb.append(" "+attribute.getName()+"=\""+attribute.getValue()+"\"");
            }
        }
        sb.append(">");
        //获得当前标签下的所有子标签
        Iterator<Node> iterator= element.nodeIterator();
        while(iterator.hasNext()) {
            Node node = iterator.next();
            //输出标签
            if(node instanceof Element) {
                Element e = (Element)node;
                getchild(e,sb);
            }
            //输出文本
            if(node instanceof Text) {
                Text text = (Text)node;
                sb.append(node.getText());
            }
        }
        sb.append("</"+element.getName()+">");  
    }
}

示例2:把xml获取的信息封装到对象内

/**
 * 把xml封装到对象中
 *
 */
public class Demo2 {
    @Test
    public void test2() throws Exception{
        SAXReader reader = new SAXReader();
        Document doc = reader.read(new File("./src/contact.xml"));
        Element elem = doc.getRootElement();
        Iterator<Element> it = elem.elementIterator();
        ArrayList<Contact> contacts = new ArrayList();
        while(it.hasNext()) {
            Contact contact = new Contact();
            Element element = it.next();
            contact.setId(element.attributeValue("id"));
            contact.setAge(element.elementText("age"));
            contact.setPhone(element.elementText("phone"));
            contact.setEmail(element.elementText("email"));
            contact.setQq(element.elementText("qq"));
            contacts.add(contact);
        }
        
        for(Contact contact:contacts) {
            System.out.println(contact);
        }
    }
}

3) 修改xml文件
增加:

修改:

删除

写入

写入基本流程:首先创构建一个空的Document对象,然后向其中按照节点关系添加标签(根标签只能有一个),然后创建文件输出流,指定输出格式,利用XMLWriter对象设置格式和写入内容,最后关闭writer对象。

示例3:创建文件并写入一个简单的XML文档:


************
/**
 * 生成xml文档
 *
<Students>
<Student id="1">
    <name>张三</name>
    <gender>男</gender>
    <grade>计算机1班</grade>
    <address>广州天河</address>
</Student>
<Student id="2">
    <name>李四</name>
    <gender>女</gender>
    <grade>计算机2班</grade>
    <address>广州越秀</address>
</Student>
</Students>
 *
 */
public class Demo3 {
    @Test
    public void test() throws Exception {
        //在内存创建Document文档
        Document doc = DocumentHelper.createDocument();
        //写入内容
        Element rootElement = doc.addElement("Students");
        //增加第二层标签
        Element studentElem = rootElement.addElement("Student");
        //增加属性
        studentElem.addAttribute("id", "1");
        //添加第三层标签
        studentElem.addElement("name").setText("张三");
        studentElem.addElement("gender").setText("男");
        studentElem.addElement("grade").setText("计算机一班");
        studentElem.addElement("address").setText("广州天河");
        //增加第二个二层标签
        Element studentElemnt2 = rootElement.addElement("Student");
        studentElemnt2.addAttribute("id", "2");
        //为第二个二层标签添加子标签
        studentElemnt2.addElement("name").setText("李四");
        studentElemnt2.addElement("gender").setText("女");
        studentElemnt2.addElement("grade").setText("计算机二班");
        studentElemnt2.addElement("address").setText("广州越秀");
        
        //将内容写出到文件
        //创建输出流
        FileOutputStream out = new FileOutputStream(new File("f:/student.xml"));
        //指定输出方式
        OutputFormat format = OutputFormat.createPrettyPrint();
        //指定编码方式
        format.setEncoding("utf-8");
        XMLWriter writer = new XMLWriter(out,format);
        //写出内容
        writer.write(doc);
        //关闭资源
        writer.close();
    }
}

示例4:修改、删除xml文件

/**
 * 修改id为2的学生的姓名+删除id为2的学生标签
 *
 */
public class Demo3 {
    @Test
    public void test() throws Exception {
        //将XML文件载入为document对象
        Document document = new SAXReader().read(new File("f:/student.xml"));
        //获取所有Student标签
        Iterator<Element> it = document.getRootElement().elementIterator("Student");
        //查询id为2的学生
        while(it.hasNext()) {
            Element elem = it.next();
            System.out.println(elem.attribute("id").getValue());
            if(elem.attributeValue("id").equals("2")) {
                //修改姓名
                //elem.element("name").setText("王丽");
                //删除该学生标签
                elem.detach();
                break;
            }
        }
        
        FileOutputStream out = new FileOutputStream("f:/student.xml");
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("utf-8");
        XMLWriter writer = new XMLWriter(out,format);
        writer.write(document);
        writer.close();
    }
}

4)xPath技术

当使用dom4j查询比较深的层次节点时比较麻烦,xPath技术可以使我们快速获得深层次节点
使用xPath的方法需要导入dom4j文件夹下的jaxen-1.1-beta-6.jar包。

xPath语法:
Xpath语法类似于在一个文件系统中定位文件
W3C的Xpath语法教程:http://www.w3school.com.cn/xpath/xpath_syntax.asp

在DOM4J中的使用方法:


SAX解析

1)SAX解析工具
SAX解析工具- Sun公司提供的。内置在jdk中。org.xml.sax.*
2)SAX解析原理
加载一点,读取一点,处理一点。对内存要求比较低。

核心的API:
SAXParser类: 用于读取和解析xml文件对象

DefaultHandler类的API:

3)示例,利用SAX解析输出完整xml文档内容
1.主函数:

/**
 * 读取contact.xml文件,完整输出文档内容
 *
 */
public class Demo2 {

    public static void main(String[] args)throws Exception {
        //1.创建SAXParser
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        //2.读取xml文件
        MyDefaultHandler2 handler = new MyDefaultHandler2();
        parser.parse(new File("./src/contact.xml"), handler);
        String content = handler.getContent();
        System.out.println(content);
    }
}

2.MyDefaultHandler2类

/**
 * SAX处理器程序
 */
public class MyDefaultHandler2 extends DefaultHandler {
    //存储xml文档信息
    private StringBuffer sb = new StringBuffer();
    
    //获取xml信息
    public String getContent(){
        return sb.toString();
    }
    

    /**
     * 开始标签
     */
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        sb.append("<"+qName);
        //判断是否有属性
        if(attributes!=null){
            for(int i=0;i<attributes.getLength();i++){
                //得到属性名称
                String attrName = attributes.getQName(i);
                //得到属性值
                String attrValue = attributes.getValue(i);
                sb.append(" "+attrName+"=\""+attrValue+"\"");
            }
        }
        sb.append(">");
    }
    
    /**
     * 文本内容
     */
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        //得到当前读取的文本
        String content = new String(ch,start,length);
        sb.append(content);
    }
    
    /**
     * 结束标签
     */
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        sb.append("</"+qName+">");
    }
}

SAX解析与DOM解析的区别

DOM解析 SAX解析
原理: 一次性加载xml文档,不适合大容量的文件读取 原理: 加载一点,读取一点,处理一点。适合大容量文件的读取
DOM解析可以任意进行增删改查 SAX解析只能读取
DOM解析任意读取任何位置的数据,甚至往回读 SAX解析只能从上往下,按顺序读取,不能往回读
DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单。 SAX解析基于事件的编程方法。java开发编码相对复杂。

XML约束

1)引入
XML语法是由w3c组织制定的规范xml文件的基本编写规则,而XML约束是开发者自定义规则以使XML符合自己的规范的约束。

2)XML约束技术
DTD约束:语法相对简单,功能也相对简单。学习成本也低。
Schema约束:语法相对复杂,功能也相对强大。学习成本相对高!!!(名称空间)

3)DTD约束
1.导入DTD方式

<?xml version="1.0"?>
<!DOCTYPE note [//定义此文档是 note 类型的文档。
  <!ELEMENT note (to,from,heading,body)>     //定义 note 元素有四个元素:"to、from、heading,、body"
  <!ELEMENT to      (#PCDATA)>               //元素为 "#PCDATA" 类型
  <!ELEMENT from    (#PCDATA)>               //元素为 "#PCDATA" 类型
  <!ELEMENT heading (#PCDATA)>               //元素为 "#PCDATA" 类型
  <!ELEMENT body    (#PCDATA)>              //元素为 "#PCDATA" 类型
]>
<note>
  <to>George</to>
  <from>John</from>
  <heading>Reminder</heading>
  <body>Don't forget the meeting!</body>
</note>

2.DTD语法

顺序问题:
<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)>: 表示子标签必须按顺序出现
次数问题:
标签名 : 表示标签必须出现且只出现1次。
标签名+ : 至少出现1次
标签名* : 0或n次。
标签名? : 0 或1次。

4)Schema约束
名称空间:告诉xml文档的哪个元素被哪个schema文档约束。 在一个xml文档中,不同的标签可以受到不同的schema文档的约束。
1.一个名称空间受到schema文档约束的情况
2.多个名称空间受到多个schema文档约束的情况
3.默认名称空间的情况
4.没有名称空间的情况

上一篇 下一篇

猜你喜欢

热点阅读