XML

XML:

     01.可扩展标记语言

     02.符合w3c标准(w3c:万维网联盟组织!规定xml,HTML,css,js,数据库......一系列的规范)

     03.着重数据的保存,不专注显示!

     04.无需预编译

以xml作为后缀名的文件,我们称之为xml文件!

例:学生信息.xml

<?xml version="1.0" encoding="gbk"?>
<school> 
  <class location="一楼" name="一班"> 
    <student name="一班小黑" age="7"/>  
    <student name="一班小白" age="5">有点悲哀</student> 
  </class>  
  <class location="二楼" name="二班"> 
    <student name="二班小黑" age="7">有点可爱</student>  
    <student name="二班小白" age="5"/> 
  </class>  
  <class location="三楼" name="三班"> 
    <student name="三班小黑" age="7">有点调皮</student>  
    <student name="三班小白" age="5"/> 
  </class> 
</school>

 注意点

     01.根节点只能有一个

     02.所有节点都是成对出现的

               <学校>开放标签

               </学校>闭合标签

     03.所有的节点必须正确的嵌套

     04.xml文件中严格区分大小写

XML的节点结构,我们称之为dom树!==》因为整个xml文件的节点结构像一个倒挂的树!

DOM:(Document Object Model)文档对象模型

XML文档中特殊字符的转换

       >      &gt;

       <      &lt;

       '       &apos;

       "      &quot;

       &     &amp;

       空格   &nbsp;

DTD文件(Document Type Definition):  针对xml文件的约束文件!

<!ELEMENT struts ((package|include|bean|constant)*, unknown-handler-stack?)>
<!ATTLIST struts
    order CDATA #IMPLIED
>

<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, default-class-ref?, global-results?, global-exception-mappings?, action*)>
<!ATTLIST package
    name CDATA #REQUIRED
    extends CDATA #IMPLIED
    namespace CDATA #IMPLIED
    abstract CDATA #IMPLIED
    strict-method-invocation CDATA #IMPLIED
    externalReferenceResolver NMTOKEN #IMPLIED
>

01.<!ELEMENT struts ((package|include|bean|constant)*, unknown-handler-stack?)>

     ELEMENT===》元素 package        (内容)===》子元素

02.<!ELEMENT package (result-types?, interceptors+, action*)>

    result-types的位置 > nterceptors的位置 > action的位置

    ? :子元素至少出现0次,最多出现1次!

     +  :子元素至少出现1次

     *   :子元素至少出现0次,最多出现N次!

03.<!ATTLIST package 

              name CDATA #REQUIRED 

              extends PCDATA #IMPLIED 
>

    ATTLIST:package元素中可以包含的属性

    name,extends  : 属性名

    CDATA : Character Data 字符数据==》解析器不会解析的文本
    PCDATA: Parsed  Character Data  被解析的字符数据==》解析器会解析的文本
    #REQUIRED :属性是必须有的
    #IMPLIED  :属性不是必须的

    Schema  可以替换 DTD, 文件的扩展名是 xsd (XML  Schema  Definition)

    解析xml文件:

      1.DOM:基于xml文档树结构的解析,把文件中的内容全部读到内存中,占内从,消耗资源多!

      2.SAX:基于事件的解析,不会把文件中的内容全部读到内存中,占用资源少!

      3.JDOM:针对于java的特定模型!满足2  8 原则!自身没有解析器,依赖于SAX2的解析器

      4.DOM4J: 是JDOM一个分支,开放源码,性能优异,功能强大!依赖于SAX的解析器

public class SchoolDemo {

      static  Scanner input=new Scanner(System.in);
      static Document document=null;//dom树
      static Element root=null;
      public static void main(String[] args) {
        System.out.println("**************进入解析xml文件世界**************");
        System.out.println("==========1.新增节点===========");
        System.out.println("==========2.删除节点===========");
        System.out.println("==========3.修改节点===========");
        System.out.println("==========4.查询节点===========");
        System.out.println("请输入您的选择:");
        int choose=input.nextInt();
        /**
         * 不管你进行什么操作,前提得有 指定xml文件的dom树
         * 学校信息.xml 我们需要解析的xml文件
         */
        String file="学校信息.xml";
        getDocment(file);
        switch(choose){
        case 1://新增节点
            addClass(file);
            break;
        case 2://删除节点
            deleteClass(file);
            break;
        case 3://修改节点
            updateClass(file);
            break;
        case 4://查询节点
            getAllClass(file);
            break;
        }        
    }
    
      /**
       * 查询节点
       */
        private static void getAllClass(String file) {
        //根据根节点获取school获取所有的class子节点集合
            Iterator <Element> classes = root.elementIterator();
            while(classes.hasNext()){
                Element clazz = classes.next();
                System.out.println("班级名称"+clazz.attributeValue("name"));
                System.out.println("班级位置"+clazz.attributeValue("location"));
                //根据class节点获取所有的student子节点集合
                Iterator <Element> students = clazz.elementIterator();
                while(students.hasNext()){
                    Element student = students.next();
                    System.out.println("学生姓名:"+student.attributeValue("name"));
                    System.out.println("学生年龄:"+student.attributeValue("age"));
                    if(!student.getTextTrim().equals("")){
                        System.out.println("这个学生的描述信息是"+student.getTextTrim());
                    }
                }
            }
        
    }

        /**
         * 修改节点
         * @param file
         */
    private static void updateClass(String file) {
        System.out.println("请您输入需要修改的class名称:");
        String className=input.next();
        System.out.println("请输入新的class名称:");
        String newclassNmae=input.next();
        //从根节点获取所有子节点
        Iterator <Element> classes = root.elementIterator();
        while(classes.hasNext()){
            Element clazz = classes.next();
            if(clazz.attributeValue("location").equals(className)){
                clazz.setAttributeValue("location", newclassNmae);
            }
        }
        if(saveXML(file)){
            System.out.println("修改成功");
        }else{
            System.out.println("修改失败");
        }
    }


    /**
     * 删除节点
     */
    private static void deleteClass(String file) {
    System.out.println("请输入需要删除的节点名称:");
    String className=input.next();
    //从根节点中获取所有的子节点
    Iterator <Element> classes = root.elementIterator();
    while(classes.hasNext()){
        Element clazz = classes.next();//获取具体的一个子元素class
        if(clazz.attributeValue("name").equals(className)){
            //删除节点 不允许自杀 必须通过父级节点删除
            classes.remove();
        }
        
    }
    
    if(saveXML(file)){
        System.out.println("删除成功");
    }else{
        System.out.println("删除失败");
    }
    }

    /**
     * 新增节点
     * @param file
     */
    private static void addClass(String file) {
        //在根节点下创建一个新节点
        Element classElement = root.addElement("class");
        //给class节点新增属性
        classElement.addAttribute("name", "四班");
        classElement.addAttribute("location", "四楼");
        //再次增加子节点student
        Element studentElement = classElement.addElement("student");
        //给student节点增加属性
        studentElement.addAttribute("name", "四班小黑");
        studentElement.addAttribute("age", "13");
        /**
         * 以上的操作相当于在内存中创建了如下内容
         * <class name="四班" location="四楼">
         *   <student name="四班小黑" age="13"></student>
         *</class>
         *
         *再次强调是在内存中!!还没有真正的保存在xml文件中;
         *
         */
        if(saveXML(file)){
            System.out.println("新增成功");
        }else{
            System.out.println("新增失败");
        }
        
    }
    
    /**
     * 把内存中的数据 真正的保存在xml文件中====》数据的持久化
     * @param file  需要持久化的文件
     * @return
     */
    private static boolean saveXML(String file) {
        XMLWriter writer=null;//创建输出流对象
        OutputFormat format=null;
        //创建输出流格式化对象
        format=OutputFormat.createPrettyPrint();
        format.setEncoding("gbk");//设置编码格式
        try {
            writer=new XMLWriter(new FileWriter(file),format);
            //真正的把dom树写入xml文件中
            writer.write(document);
        } catch (IOException e) {
            
            e.printStackTrace();
            return false;
        }finally{//关闭输出流
            try {
                writer.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return true;
    }

    /**
     * 目的:获取dom树
     * 需要 解析的xml文件
     */
    private static void getDocment(String file) {
        SAXReader reader=new SAXReader();//创建解析器对象
        try {
            document  = reader.read(file);//获取dom树
            root=document.getRootElement();//获取根节点
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        
    }

}
原文地址:https://www.cnblogs.com/liutianci/p/8243501.html