XML

XML不多总结,值得一提的是,XML中对特殊字符的处理。
这里写图片描述
如果在XML中有大量的特殊字符,可以使用CDATA处理。
CDATA中的所有字节都会被当做字符数据的常量部分。
语法:<![CDATA[ ]]>
XML注释语法:<!-----注释内容------>


重点是解析XML。这里总结两种方式。

DOM解析方式:
DOM是 基于XML的数结构来完成解析的。DOM解析文档时,会根据读取的文档,构建一个驻留内存的树结构,然后使用DOM接口来操作这个树结构。因为整个DOM数是驻留在内存中的,所以进行各种访问操作时非常方便。DOM解析的方式非常适用于多次访问XML的程序,但是DOM解析是比较消耗资源的。

<?xml version="1.0" encoding="GB2312"?>
<PhoneInfo>
    <Brand name="华为">
        <Type name="P9" />
    </Brand>
    <Brand name="苹果">
        <Type name="iphone6" />
        <Type name="iphone7" />
    </Brand>
</PhoneInfo>
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
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 DOMParseDemo {
    // 创建全局Document文档对象
    Document doc = null;

    /*
     * 加载xml文件到内存中
     */
    public void loadDocument() {
        try {
            // 得到DOM解析器的工厂实例
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            // 从DOM工厂获得DOM解析器
            DocumentBuilder db = dbf.newDocumentBuilder();
            // 利用DOM解析器解析到内存中
            doc = db.parse("收藏信息.xml");
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
    }

    /*
     * 显示所有的Brand
     */
    public void showInfo() {
        // 要显示所有的Brand首先要得到所有的Brand节点列表信息
        NodeList brandList = doc.getElementsByTagName("Brand");
        // 首先循环Brand信息
        for (int i = 0; i < brandList.getLength(); i++) {
            // 获取每个Brand节点的信息
            Node brand = brandList.item(i);
            // 获取每个Brand节点的name元素的值
            Element element = (Element) brand;
            String attrValue = element.getAttribute("name");
            // 获取每个Brand元素的所有子元素
            // 首先先获取每个Brand元素的所有子元素
            NodeList types = element.getChildNodes();
            // 循环每个子元素输出每个子元素的name属性值
            for (int j = 0; j < types.getLength(); j++) {
                Node typeNode = types.item(j);
                // 遍历时会有空格。如果当前Node是一个Element,才进行转换
                if (typeNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element typeElement = (Element) typeNode;
                    // 获取此ElementName属性
                    String typeStr = typeElement.getAttribute("name");
                    System.out.println("手机:" + attrValue + ",型号" + typeStr);
                }
            }
        }
    }

    /*
     * 保存XML文件
     */
    public void saveXML(String path) {
        try {
            // 用转换工厂创建转换对象
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer newTransformer = factory.newTransformer();
            // 创建资源文档
            DOMSource domSource = new DOMSource(doc);
            // 设置编码格式
            newTransformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
            StreamResult result = new StreamResult(path);
            // 把DOM数转化为XML文件
            newTransformer.transform(domSource, result);
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }
    /*
     * 增加节点信息操作
     */
    public void addNewPhoneInfo(){
        //创建Brand节点
        Element brandElement = doc.createElement("Brand");
        //设置节点信息
        brandElement.setAttribute("name", "三星");
        //创建子节点
        Element typeElement=doc.createElement("Type");
        typeElement.setAttribute("name", "Node8");
        //最后添加父子关系,先从底层添加父子关系,把Type挂到Brand上
        brandElement.appendChild(typeElement);
        //最后挂到最高节点PhoneInfo上,首先得获取PhoneInfo节点,然后获取第一个节点(下标为0),然后加上子节点
        doc.getElementsByTagName("PhoneInfo").item(0).appendChild(brandElement);    
    }
    /*
     * 更新节点信息操作
     * 把name为三星的Brand改为SAMSUNG
     */
    public void modifyPhoneInfo() { 
        // 先获取所有Brand的节点列表
        NodeList list = doc.getElementsByTagName("Brand");
        // 循环Brand的list列表
        for (int i = 0; i < list.getLength(); i++) {
            //获取每个元素
            Node brandNode = list.item(i);
            Element ele = (Element) brandNode;
            // 获取每个元素的第一个属性name的值
            String brandName = ele.getAttribute("name");
            // 判断操作,如果name的值为三星,就设置为SAMSUNG
            if (brandName.equals("三星")) {
                ele.setAttribute("name", "SAMSUNG");
            }
        }
    }
    /*
     * 删除节点操作
     * 删除SANSUNG
     */
    public void delPhoneInfo(){
        //先获取所有的Brand列表
        NodeList list = doc.getElementsByTagName("Brand");
        //循环Brand的list列表
        for(int i=0;i<list.getLength();i++){
            Element ele = (Element) list.item(i);
            // 获取每个元素的第一个属性name的值
            String attribute = ele.getAttribute("name");
            if(attribute.equals("SAMSUNG")){
                //要通过父节点来删除子节点
               ele.getParentNode().removeChild(ele);
            }
        }
    }
    public static void main(String[] args) {
        DOMParseDemo dom = new DOMParseDemo();
        dom.loadDocument();
        dom.addNewPhoneInfo();
        dom.modifyPhoneInfo();
        dom.delPhoneInfo();
        dom.saveXML("练习的收藏信息.xml");
        dom.showInfo();
    }
}

DOM4J解析方式:
DOM4J是一种非常优秀的JAVA XML API,具有卓越的性能。功能强大并且易用。
同时也是开源的软件。如今越来越多的java软件都在使用DOM4J来读写XML。
Sun公司的JAVAXM也在使用DOM4J。

<?xml version="1.0" encoding="GB2312"?>
<PhoneInfo>
    <Brand name="华为">
        <Type name="P9" />
    </Brand>
    <Brand name="苹果">
        <Type name="iphone6" />
        <Type name="iphone7" />
    </Brand>
</PhoneInfo>
/*
 * 使用DOM4J解析XML文件
 */
public class DOM4JXMLParse {
    Document doc=null;
    /*
     * 加载xml文件的方法
     */
    public void loadDocument(){
        try {
            //加载xml文件到内存中来
            SAXReader saxReader=new SAXReader();
            doc = saxReader.read("收藏信息.xml");
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
    /*
     * 保存XML
     */
    public void saveXML(String path){
        //创建一个pretty的格式化器
        OutputFormat format=OutputFormat.createPrettyPrint();
        //写文件操作
        try {
            XMLWriter writer=new XMLWriter(new FileWriter(path), format);
            //写入文档对象
            writer.write(doc);
            //及时关闭写入流操作
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*
     * 显示DOM信息
     */
    public void showInfo(){
        //得到整个DOM数的根节点
        Element root = doc.getRootElement();
        //得到根节点的子节点集合
        Iterator iterator = root.elementIterator();
        //遍历集合
        while(iterator.hasNext()){
            Element brandEle = (Element) iterator.next();
            //获取第一层的name属性的值
            String brandStr = brandEle.attributeValue("name");
            //获取第一层节点的下一层的节点值,DOM4J中已经做了判断,不需判断是否为Element对象
            Iterator itType = brandEle.elementIterator();
            //循环第一层的所有子节点
            while(itType.hasNext()){
                Element typeEle=(Element) itType.next();
                String typeStr = typeEle.attributeValue("name");
                System.out.println("手机:"+brandStr+",型号:"+typeStr);
            }

        }
    }
    /*
     * 新增节点
     * (三星  S8)
     */
    public void addPhoneInfo(){
        //首先拿到根节点
        Element root= doc.getRootElement();
        //在根节点下创建子节点
        Element brandElement = root.addElement("Brand");
        //给子节点设置属性
        brandElement.addAttribute("name", "三星 ");
        //给子节点创建下一个子节点
        Element typeElement=brandElement.addElement("Type");
        //设置属性
        typeElement.addAttribute("name", "Note8");
    }
    /*
     * 修改节点信息
     * 为每一个节点添加一个id信息
     */
    public void modifyPhoneInfo(){
        //首先拿到根节点
        Element root = doc.getRootElement();
        //定义计数器
        int id=0;
        //获取所有节点的iterator。
        Iterator itBrand = root.elementIterator();
        //遍历获取每个brand
        while(itBrand.hasNext()){
            id++;
            //遍历下一个
            Element brandele=(Element) itBrand.next();
            //为每个节点增加id属性
            brandele.addAttribute("id", id+"");
        }
    }
    /*
     * 删除节点操作
     * 删除节点三星
     */
    public void delPhoneInfo(){
        //首先获取根节点
        Element root = doc.getRootElement();
        //得到所有的子节点
        Iterator itBrand = root.elementIterator();
        while(itBrand.hasNext()){
            Element ele=(Element) itBrand.next();
            if(ele.attributeValue("name").equals("三星")){
                //若找到name的值为三星的节点,则由此节点的父节点来移除此节点
                ele.getParent().remove(ele);
            }
        }
    }
    public static void main(String[] args) {
        DOM4JXMLParse dom4j=new DOM4JXMLParse();
        dom4j.loadDocument();
        dom4j.modifyPhoneInfo();
        dom4j.showInfo();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值