XML

XML


XML作用

  1. 作为软件的配置文件
  2. 作为小型的数据库

XML语法

标签

语法: <student></student>开始标签 标签体内容 结束标签
1)<student/><student></student> 空标签。没有标签体内容
2)xml标签名称区分大小写。
3)xml标签一定要正确配对。
4)xml标签名中间不能使用空格
5)xml标签名不能以数字开头
6)注意: 在一个xml文档中,有且仅有一个根标签

属性

语法: <Student name="eric">student</Student>
注意:
1)属性值必须以引号包含,不能省略,也不能单双引号混用!!!
2)一个标签内可以有多个属性,但不能出现重复的属性名!!!

注释

 <!--  xml注释 -->

文档声明

语法: <?xml version="1.0" encoding="utf-8"?>
version: xml的版本号
encoding: 解析xml文件时查询的码表(解码过程时查询的码表)
注意:
1)如果在ecplise工具中开发xml文件,保存xml文件时自动按照文档声明的encoding来保存文 件。
2)如果用记事本工具修改xml文件,注意保存xml文件按照文档声明的encoding的码表来保存。

转义字符

在xml中内置了一些特殊字符,这些特殊字符不能直接被浏览器原样输出。如果希望把这些特殊字符按照原样输出到浏览器,对这些特殊字符进行转义。转义之后的字符就叫转义字节。

特殊字符转义字符
<&lt;
>&gt;
&quot;
&&amp;
空格&nsbp;

CDATA块

作用: 可以让一些需要进行包含特殊字符的内容统一进行原样输出。
语法:

<![CDATA[ 内容 ]]>
               <![CDATA[
                    <itcast>
                             <br/>
                    </itcast>
               ]]>

处理指令

作用: 告诉xml解析器如何解析xml文档
处理指令以“<?”作为开头,以“?>”作为结尾,XML声明语句就是最常见的一种处理指令
案例: <?xml-stylesheet type="text/css" href="1.css"?> 告诉xml解析该xml文档引用了哪个css文件。
需要提取xml内容可以使用xml-stylesheet指令

XML解析

  1. DOM解析原理: 使用树形模型,把XML文档转化为一个包含其内容的树,并可以对树进行遍历。
    1)JAXP (oracle-Sun公司官方工具)
    2)JDOM工具(非官方、民间组织)
    3)Dom4J工具(非官方,相当好用)
    三大框架(默认读取xml的工具就是Dom4j)
  2. SAX解析原理:采用了基于事件的模型,解析XML文档的时候可以触发一系列的事件。
    1)Sax解析工具(oracle-sun公司官方)

Dom4j

什么是dom解析

DOM解析原理:xml解析器一次性把整个xml文档加载进内存,然后在内存中构建一颗Document的对象树,通过Document对象,得到树上的节点对象,通过节点对象访问(操作)到xml文档的内容。
这里写图片描述

Dom4j工具

非官方,不在jdk中。
使用步骤:
1)导入dom4j的核心包。 dom4j-1.6.1.jar

Dom4j操作xml案例

  1. 读取xml文档(标签、属性、文本)
    contact.xml
<?xml version="1.0" encoding="utf-8"?>
<contactList>
    <contact id="001">
        <name>张三</name>
        <age>20</age>
        <phone>134222223333</phone>
        <email>zhangsan@qq.com</email>
        <qq>432221111</qq>
    </contact>
    <contact id="002">
        <name>李四</name>
        <age>20</age>
        <phone>134222225555</phone>
        <email>lisi@qq.com</email>
        <qq>432222222</qq>
    </contact>
</contactList>
import java.io.File;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;

/**
 1. dom4j读取xml文件内容
 2. 节点
 3. 标签
 4. 属性
 5. 文本
 6. @author APPle
 7.  */
public class Demo2 {
    /**
     * 遍历xml文档的所有节点
     * @throws Exception
     */
    @Test
    public void test2() throws Exception{
        //1.读取xml文档,返回Document对象
        SAXReader reader = new SAXReader();
        Document doc = reader.read(new File("./src/contact.xml"));

        //得到根标签
        Element rooElem = doc.getRootElement();

        getChildNodes(rooElem);

    }

    /**
     * 获取 传入的标签下的所有子节点
     * @param elem
     */
    private void getChildNodes(Element elem){
        System.out.println(elem.getName());

        //得到子节点
        Iterator<Node> it = elem.nodeIterator();
        while(it.hasNext()){
            Node node = it.next();

            //1.判断是否是标签节点
            if(node instanceof Element){
                Element el = (Element)node;
                //递归
                getChildNodes(el);
            }
        };
    }

    /**
     * 获取标签
     */
    @Test
    public void test3() throws Exception{
        //1.读取xml文档,返回Document对象
        SAXReader reader = new SAXReader();
        Document doc = reader.read(new File("./src/contact.xml"));

        //2.得到根标签
        Element  rootElem = doc.getRootElement();
        //得到标签名称
        String name = rootElem.getName();
        System.out.println(name);

        //3.得到当前标签下指定名称的第一个子标签
        /*
        Element contactElem = rootElem.element("contact");
        System.out.println(contactElem.getName());
        */

        //4.得到当前标签下指定名称的所有子标签
        /*
        Iterator<Element> it = rootElem.elementIterator("contact");
        while(it.hasNext()){
            Element elem = it.next();
            System.out.println(elem.getName());
        }
        */

        //5.得到当前标签下的的所有子标签
        List<Element> list = rootElem.elements();
        //遍历List的方法
        //1)传统for循环  2)增强for循环 3)迭代器
        /*for(int i=0;i<list.size();i++){
            Element e = list.get(i);
            System.out.println(e.getName());
        }*/

    /*  for(Element e:list){
            System.out.println(e.getName());
        }*/
        /*
        Iterator<Element> it = list.iterator(); //ctrl+2 松开 l
        while(it.hasNext()){
            Element elem = it.next();
            System.out.println(elem.getName());
        }*/

        //获取更深层次的标签(方法只能一层层地获取)
        Element nameElem = doc.getRootElement().
                    element("contact").element("name");
        System.out.println(nameElem.getName());

    }

    /**
     * 获取属性
     */
    @Test
    public void test4() throws Exception{
        //1.读取xml文档,返回Document对象
        SAXReader reader = new SAXReader();
        Document doc = reader.read(new File("./src/contact.xml"));

        //获取属性:(先获的属性所在的标签对象,然后才能获取属性)
        //1.得到标签对象
        Element contactElem = doc.getRootElement().element("contact");
        //2.得到属性
        //2.1  得到指定名称的属性值
        /*
        String idValue = contactElem.attributeValue("id");
        System.out.println(idValue);
        */

        //2.2 得到指定属性名称的属性对象
        /*Attribute idAttr = contactElem.attribute("id");
        //getName: 属性名称    getValue:属性值
        System.out.println(idAttr.getName() +"=" + idAttr.getValue());*/

        //2.3 得到所有属性对象,返回LIst集合
        /*List<Attribute> list = contactElem.attributes();
        //遍历属性
        for (Attribute attr : list) {
            System.out.println(attr.getName()+"="+attr.getValue());
        }*/

        //2.4 得到所有属性对象,返回迭代器
        Iterator<Attribute> it = contactElem.attributeIterator();
        while(it.hasNext()){
            Attribute attr = it.next();
            System.out.println(attr.getName()+"="+attr.getValue());
        }

    }

    /**
     * 获取文本
     */
    @Test
    public void test5() throws Exception{
        //1.读取xml文档,返回Document对象
        SAXReader reader = new SAXReader();

         Document doc = reader.read(new File("./src/contact.xml"));


        /**
         * 注意: 空格和换行也是xml的内容
         */
        String content = doc.getRootElement().getText();
        System.out.println(content);


        //获取文本(先获取标签,再获取标签上的文本)
        Element nameELem = 
            doc.getRootElement().element("contact").element("name");
        //1. 得到文本
        String text=nameELem.getText();
        System.out.println(text);

        //2. 得到指定子标签名的文本内容
        String text2 = 
            doc.getRootElement().element("contact").elementText("phone");
        System.out.println(text2);

    }
}

2、 修改xml文档(标签、属性、文本)

import java.io.File;
import java.io.FileOutputStream;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;

/**
 * 修改xml内容
 * 增加:文档,标签 ,属性
 * 修改:属性值,文本
 * 删除:标签,属性
 * @author APPle
 *
 */
public class Demo3 {

    /**
     * 增加:文档,标签 ,属性
     */
    @Test
    public void test1() throws Exception{
        /**
         * 1.创建文档
         */
        Document doc = DocumentHelper.createDocument();
        /**
         * 2.增加标签
         */
        Element rootElem = doc.addElement("contactList");
        //doc.addElement("contactList");
        Element contactElem = rootElem.addElement("contact");
        contactElem.addElement("name");
        /**
         * 3.增加属性
         */
        contactElem.addAttribute("id", "001");
        contactElem.addAttribute("name", "eric");

        //把修改后的Document对象写出到xml文档中
        FileOutputStream out = new FileOutputStream("e:/contact.xml");
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("utf-8");
        XMLWriter writer = new XMLWriter(out,format);
        writer.write(doc);
        writer.close();
    }

    /**
     * 修改:属性值,文本
     * @throws Exception
     */
    @Test
    public void test2() throws Exception{
        Document doc = new SAXReader().read(new File("./src/contact.xml"));

        /**
         * 方案一: 修改属性值   1.得到标签对象 2.得到属性对象 3.修改属性值
         */
        //1.1  得到标签对象
        /*
        Element contactElem = doc.getRootElement().element("contact");
        //1.2 得到属性对象
        Attribute idAttr = contactElem.attribute("id");
        //1.3 修改属性值
        idAttr.setValue("003");
        */
        /**
         * 方案二: 修改属性值
         */
        //1.1  得到标签对象
        /*
        Element contactElem = doc.getRootElement().element("contact");
        //1.2 通过增加同名属性的方法,修改属性值
        contactElem.addAttribute("id", "004");
        */

        /**
         * 修改文本 1.得到标签对象 2.修改文本
         */
        Element nameElem = doc.getRootElement().
            element("contact").element("name");
        nameElem.setText("李四");

        FileOutputStream out = new FileOutputStream("e:/contact.xml");
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("utf-8");
        XMLWriter writer = new XMLWriter(out,format);
        writer.write(doc);
        writer.close();
    }


    /**
     * 删除:标签,属性
     * @throws Exception
     */
    @Test
    public void test3() throws Exception{
        Document doc = new SAXReader().read(new File("./src/contact.xml"));

        /**
         * 1.删除标签     1.1 得到标签对象  1.2 删除标签对象    
         */
        // 1.1 得到标签对象
        /*
        Element ageElem = doc.getRootElement().element("contact")
                    .element("age");

        //1.2 删除标签对象
        ageElem.detach();
        //ageElem.getParent().remove(ageElem);
        */
        /**
         * 2.删除属性   2.1得到属性对象  2.2 删除属性
         */
        //2.1得到属性对象
        //得到第二个contact标签
        Element contactElem = (Element)doc.getRootElement().
            elements().get(1);
        //2.2 得到属性对象
        Attribute idAttr = contactElem.attribute("id");
        //2.3 删除属性
        idAttr.detach();
        //idAttr.getParent().remove(idAttr);

        FileOutputStream out = new FileOutputStream("e:/contact.xml");
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("utf-8");
        XMLWriter writer = new XMLWriter(out,format);
        writer.write(doc);
        writer.close();
    }
}

xPath

xPath的作用

直接使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦!!!xPath是一门在XML文档中查找信息的语言,主要是用于快速获取所需的节点对象。Dom4j内置了xPath技术,可以很方面的使用

dom4j中使用xPath

1)导入xPath支持jar包 。 jaxen-1.1-beta-6.jar
2)使用xpath方法(两个方法)
List<Node> selectNodes("xpath表达式"); 查询多个节点对象
Node selectSingleNode("xpath表达式"); 查询一个节点对象

xPath表达式

符号意义解释
/绝对路径表示从xml的根位置开始或子元素(一个层次结构)
//相对路径表示不分任何层次结构的选择元素。
*通配符表示匹配所有元素
[]条件表示选择什么条件下的元素
@属性表示选择属性节点
and关系表示条件的与关系(等价于&&)
text()文本表示选择文本内容

案例

1、删除id为2的学生标签
student.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>
import java.io.File;
import java.io.FileOutputStream;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
 * 第一个xPath程序:删除id为2的学生标签
 */
public class Demo1 {

    public static void main(String[] args) throws Exception{

        Document doc = new SAXReader().read(new File("e:/student.xml"));

        //查询一个节点对象
        Element stuElem = (Element)doc.selectSingleNode("//Student[@id='2']");

        //2.删除
        stuElem.detach();

        //3.写出xml文件
        FileOutputStream out = new FileOutputStream("e:/student.xml");
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("utf-8");
        XMLWriter writer = new XMLWriter(out,format);
        writer.write(doc);
        writer.close();
    }
}

2、xPath表达式语法

import java.io.File;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

/**
 * 学习xPath表达式语法
 * @author APPle
 *
 */
public class Demo2 {

    public static void main(String[] args) throws Exception {
        Document doc = new SAXReader().read(new File("./src/contact.xml"));

        String xpath = "";

        /**
         * 1.   /      绝对路径      表示从xml的根位置开始或子元素(一个层次结构)
         */
        xpath = "/contactList";
        xpath = "/contactList/contact";

        /**
         * 2. //     相对路径       表示不分任何层次结构的选择元素。
         */
        xpath = "//contact/name";
        xpath = "//name";

        /**
         * 3. *      通配符         表示匹配所有元素
         */
        xpath = "/contactList/*"; //根标签contactList下的所有子标签
        xpath = "/contactList//*";//根标签contactList下的所有标签(不分层次结构)

        /**
         * 4. []      条件           表示选择什么条件下的元素
         */
        //带有id属性的contact标签
        xpath = "//contact[@id]";
        //第二个的contact标签
        xpath = "//contact[2]";
        //选择最后一个contact标签
        xpath = "//contact[last()]";

        /**
         * 5. @     属性            表示选择属性节点
         */
        xpath = "//@id"; //选择id属性节点对象,返回的是Attribute对象
        xpath = "//contact[not(@id)]";//选择不包含id属性的contact标签节点
        xpath = "//contact[@id='002']";//选择id属性值为002的contact标签
        xpath = "//contact[@id='001' and @name='eric']";//选择id属性值为001,且name属性为eric的contact标签

        /**
         *6.  text()   表示选择文本内容
         */
        //选择name标签下的文本内容,返回Text对象
        xpath = "//name/text()";
        xpath = "//contact/name[text()='张三']";//选择姓名为张三的name标签  

        List<Node> list = doc.selectNodes(xpath);
        for (Node node : list) {
            System.out.println(node);
        }
    }
}

SAX

原理

边加载边读取。基于事件的编程,对内存要求比较低。

解析工具和核心API

Sun公司提供的。内置在jdk中。org.xml.sax.*
核心的API
SAXParser类: 用于读取和解析xml文件对象
parse(File f, DefaultHandler dh)方法: 解析xml文件
参数一: File:表示 读取的xml文件。
参数二: DefaultHandler: SAX事件处理程序。使用DefaultHandler的子类
DefaultHandler类的API:
void startDocument() : 在读到文档开始时调用
void endDocument() :在读到文档结束时调用
void startElement(String uri, String localName, String qName, Attributes attributes) :读到开始标签时调用
void endElement(String uri, String localName, String qName) :读到结束标签时调用
void characters(char[] ch, int start, int length) : 读到文本内容时调用

案例

1、第一个SAX读取xml文件程序

import java.io.File;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

/**
 * 第一个SAX读取xml文件程序
 * @author APPle
 *
 */
public class Demo1 {
    public static void main(String[] args) throws Exception{
        //1.创建SAXParser对象
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();

        //2.调用parse方法
        /**
         * 参数一: xml文档
         * 参数二: DefaultHandler的子类
         */
        parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());
    }
}
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
 * SAX处理程序(如何解析xml文档)
 * @author APPle
 *
 */
public class MyDefaultHandler extends DefaultHandler {

    /**
     * 开始文档时调用
     */
    @Override
    public void startDocument() throws SAXException {
        System.out.println("MyDefaultHandler.startDocument()");
    }

    /**
     * 开始标签时调用
     * @param qName: 表示开始标签的标签名
     * @param attributes: 表示开始标签内包含的属性列表
     */
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        System.out.println("MyDefaultHandler.startElement()-->"+qName);
    }

    /**
     * 结束标签时调用
     * @param qName: 结束标签的标签名称
     */
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        System.out.println("MyDefaultHandler.endElement()-->"+qName);
    }

    /**
     * 读到文本内容的时调用
     * @param ch: 表示当前读完的所有文本内容
     * @param start: 表示当前文本内容的开始位置
     * @param length: 表示当前文本内容的长度
     */ 
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        //得到当前文本内容
        String content = new String(ch,start,length);
        System.out.println("MyDefaultHandler.characters()-->"+content);
    }

    /**
     * 结束文档时调用
     */
    @Override
    public void endDocument() throws SAXException {
        System.out.println("MyDefaultHandler.endDocument()");
    }
}

2、读取contact.xml,输出完整的文档

import java.io.File;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

/**
 * 读取contact.xml文件,完整输出文档内容
 * @author APPle
 *
 */
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);
    }
}
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
 * SAX处理器程序
 * @author APPle
 */
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+">");
    }
}

dom和SAX的对比

dom和SAX对比

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值