Java框架基础-XML文档

一、XML简介

XML是Extensible Markup Language的缩写,即可扩展标记语言,是一种简单的存储语言,使用一系列简单的标记来描述结构化数据。

XML的特点

  1. XML与操作系统、编程语言的开发平台都无关。
  2. 规范统一,实现不同系统之间的数据交互。

XML的文档结构

1.声明(Declaration)

XML文档通常以XML声明开始,它定义了文档的版本和编码方式。这通常位于文档的第一行,如下所示:

<?xml version="1.0" encoding="UTF-8"?>

XML声明由以下几个部分组成:

  • version: 文档符合XML1.0规范。
  • encoding: 文档字符编码,默认值为UTF-8。

2.标签(Label)

在XML中,通过用尖括号<>括起来的各种标签(Tag)来标记数据,标签成对使用来界定字符数据。例如,<author>张三</author>中,<author>是开始标签,</author>是结束标签,张三是标签描述的内容,表示作者信息。

注意:
   XML标签必须正确结束并正确地嵌套,缺少结束标签及如下的嵌套方式是错误的。

<tile>
  <name>XML编程
</title>
</name>
//这是一个错误的示范

3.元素(Elements)

XML文档由一系列的元素组成。元素由开始标签、结束标签和(可选的)内容组成。开始标签和结束标签包含元素的名称,而内容则是元素所包含的文本或其他元素。

<person>
    <title>你好!</title>
    <author>张三</author>
</person>
  • <person><title><author> 是元素的开始标签。
  • </person></title></author> 是元素的结束标签。
  • “你好!” 和 “张三” 是元素的内容。

元素的命名规则如下:

  • 名称中可以包含字母、数字或其他的字符。
  • 名称不能以数字或标点符号开始。
  • 名称不能以字符“XML”(XML、Xml)开始。
  • 名称中不能包含空格。
    元素允许是空元素,如<title></title>,</title/>的元素写法是允许的。

4.根元素(Root Element)

每个XML文档必须有且仅有一个根元素,如"<persons>``</persons>"。
根元素的特点如下:

  • 根元素是一个完全包括文档中其他所有元素的元素。
  • 根元素的起始标签要放在所有其他元素的起始标签之前。
  • 根元素的结束标签要放在所有其他元素的结束标签之后。

5.属性(Attributes)

元素可以有属性,这些属性提供了关于元素的额外信息。属性总是包含在开始标签中,并且由名称和值组成,使用等号 (=) 分隔,并用引号包围值。

<person id="1">
    <title>你好!</title>
    <author>张三</author>
</person>
  • id="1"是<person>元素的属性。语法:
<元素名 属性名="属性值">
//属性值用引号包裹

注意:
1:一个元素可以有多个属性,多个属性之间用空格隔开,基本格式如下:
<元素名 属性名=“属性值” 属性名=“属性值”/>
2:属性值中不能直接包含<、"、&。
3:属性可以加在任何一个元素的起始标签上,但不能加在结束标签上。

6.XML中的特殊字符的处理

在XML中,有时在元素的文本中会涉及一些特殊字符(如<、>、'、"、&),而XML文档结构本身就用到这几个特殊字符,这会引起文档结构解析错误。有以下两种办法可以正常地解析包含特殊字符的内容。
(1)对这5个字符进行转义,也就是使用XML中的预定义实体代替这些字符。XML中的预定义实体和特殊字符的对应关系如下表所示。

特殊字符实体名称
<&lt;
>&gt;
&&amp;
"&quot;
&apos;

(2)在元素的文本中使用CDATA节处理。CDATA节中的所有字符都会被当作元素字符数据的常量部分,而不是XML标签。定义CDATA节的语法如下(推荐)
语法:

<![CDATA[
	要显示的字符
]]>

7.注释

注释的语法如下。

<!-- 注释内容 -->

8.格式良好的XML文档

格式良好的XML文档需要遵循如下规则。

  • 有XML声明语句。
  • 有且仅有一个根元素。
  • 标签大小写敏感。
  • 标签大小写敏感。
  • 标签成对/空标签关闭。
  • 元素正确嵌套。

二、DOM读取XML数据

在Java中,你可以使用javax.xml.parsers包中的DocumentBuilderFactory和DocumentBuilder类来解析XML文件。以下是一个简单的Java代码示例,展示了如何使用这些类来读取和解析XML文件:

首先,确保你的XML文件(例如学员信息.xml)是有效的,并且与上面的示例类似:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<scores>
    <student id="1">
        <name>李煜</name>
        <course>语文</course>
        <score>95</score>
    </student>
    <student id="2">
        <name>陈晓薇</name>
        <course>数学</course>
        <score>90</score>
    </student>
</scores>

然后,你可以使用以下Java代码来解析这个XML文件:

package ch02.jianda;

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;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class XMLStudent {

    public static void main(String[] args) {
        XMLStudent student =new XMLStudent();
        student.getDocument();
        student.showInFo();
        student.universal();
    }

    Document doc = null;

    public void getDocument(){
        //获取解析器工厂
        DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
        //获取解析器
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            //加载DOM树
            doc = builder.parse("src/main/java/学员信息.xml");
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }
    }

    public void showInFo(){
        NodeList studentList = doc.getElementsByTagName("student");
        for (int i = 0; i < studentList.getLength(); i++) {
            Element student = (Element) studentList.item(i);

            //获取并打印姓名
            Element nameElement = (Element) student.getElementsByTagName("name").item(0);
            String name = nameElement.getFirstChild().getNodeValue();

            //获取并打印学科
            Element courseElement = (Element) student.getElementsByTagName("course").item(0);
            String course = courseElement.getFirstChild().getNodeValue();

            //获取并打印分数
            Element scoreElement = (Element) student.getElementsByTagName("score").item(0);
            String score = scoreElement.getFirstChild().getNodeValue();

            System.out.println("学员信息  姓名:"+name+"\t学科:"+course+"\t分数:"+score);
        }
    }

    public void universal(){
        //添加一个学员的成绩信息(id为3)
        Element root = doc.getDocumentElement();
        Element newStudent = doc.createElement("student");
        newStudent.setAttribute("id", "3");

        Element newName = doc.createElement("name");
        newName.setTextContent("刘宇航");
        newStudent.appendChild(newName);

        Element newCourse = doc.createElement("course");
        newCourse.setTextContent("英语");
        newStudent.appendChild(newCourse);

        Element newScore = doc.createElement("score");
        newScore.setTextContent("85");
        newStudent.appendChild(newScore);

        root.appendChild(newStudent);

        //修改id为2的成绩为60
        NodeList studentList = doc.getElementsByTagName("student");
        for (int i = 0; i < studentList.getLength(); i++) {
            Node studentNode = studentList.item(i);
            if (studentNode.getNodeType() == Node.ELEMENT_NODE) {
                Element studentElement = (Element) studentNode;
                if ("2".equals(studentElement.getAttribute("id"))) {
                    NodeList scoreList = studentElement.getElementsByTagName("score");
                    if (scoreList.getLength() > 0) {
                        Element scoreElement = (Element) scoreList.item(0);
                        scoreElement.setTextContent("60");
                    }
                    break;
                }
            }
        }

        //删除id为1的成绩
        for (int i = 0; i < studentList.getLength(); i++) {
            Node studentNode = studentList.item(i);
            if (studentNode.getNodeType() == Node.ELEMENT_NODE) {
                Element studentElement = (Element) studentNode;
                if ("1".equals(studentElement.getAttribute("id"))) {
                    studentElement.getParentNode().removeChild(studentElement);
                    break;
                }
            }
        }

        try {
            //保存XML文件
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource domSource = new DOMSource(doc);
            //设置编码类型
            transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
            StreamResult result = new StreamResult(new FileOutputStream("src/main/java/学员信息.xml"));
            //把DOM树转换为XML文件
            transformer.transform(domSource,result);
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        System.out.println("XML文件已修改并保存。");
    }
}

运行后的学员信息.xml的universal()方法结果为:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<scores>
    <student id="2">
        <name>陈晓薇</name>
        <course>数学</course>
        <score>60</score>
    </student>
    <student id="3">
        <name>刘宇航</name>
        <course>英语</course>
        <score>85</score>
    </student>
</scores>

这段代码首先使用DocumentBuilderFactory和DocumentBuilder来解析XML文件,并获取Document对象。然后,它找到根元素并遍历所有<student>元素。对于每个<student>元素,它使用辅助方法getTagValue来获取<name><course><score>标签的值,并将这些值打印到控制台。

三、DOM4J解析XML

下面是使用DOM4J解析学员信息.xml文档,从控制台输出所有学员信息。

package ch02.jianda;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.net.MalformedURLException;

public class DOM4JStudent {
    public static void main(String[] args) {
        Document doc = null;
        try {
            SAXReader saxReader = new SAXReader();
            doc = saxReader.read(new File("src/main/java/学员信息.xml"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        //获取XML的根节点
        Element root = doc.getRootElement();
        for(Object obj : root.elements("student")){
            Element student = (Element) obj;
            //获取并输出id、name、course和score
            String id = student.attributeValue("id");
            String name = student.elementText("name");
            String course = student.elementText("course");
            String score = student.elementText("score");
            System.out.println("学员id:"+id+"\t姓名:"+name+"\t学科:"+course+"\t成绩:"+score);
        }
    }
}

运行结果:
在这里插入图片描述

  • 12
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值