当前位置: 首页 > news >正文

一篇文章了解XML

一、什么是 XML?

XML 是一种结构化数据的标记语言,用来存储传输描述数据。

它和 HTML 很像,但它的标签是自定义,不限定格式和外观,而是强调数据的结构和含义

XML不是用来展示数据的,HTML是用来展示数据的。

示例:

<student><name>小明</name><age>20</age><major>计算机</major>
</student>

它表示一个学生,包含姓名、年龄和专业。这就叫结构化数据。

二、XML的作用

XML 数据格式最主要的功能就是:数据传输

XML 数据格式主要的用途又有哪些?

  • 程序之间的数据传输通讯
  • 配置文件 config.xml
  • 存储数据,充当小型数据库 data.xml

规范数据格式,是数据具有结构性,易读易处理。

场景说明
配置文件如 Spring 的 applicationContext.xml、MyBatis 配置
数据存储可用作小型数据库、日志、缓存数据
网络传输WebService(SOAP)以前就是基于 XML
数据交换不同系统之间用 XML 传数据(如银行系统)

 

三、XML 的语法规则

基本结构:

<?xml version="1.0" encoding="UTF-8"?>  <!-- XML 声明,非必需但推荐写 -->
<root><element>内容</element>
</root>

XML 的 6 个语法规则:

规则说明示例
必须有根元素整个文档必须有且只有一个根节点<root>...</root>
标签成对出现开始标签和结束标签必须配对<name>Tom</name>
标签区分大小写<Name><name>严格匹配
属性必须加引号属性值必须用引号包裹<person gender="male"/>
空标签可以简写没有内容的标签可以自闭合<br />
不能有非法字符<, & 不能直接出现在内容中&lt;, &amp;

XML 和 HTML 有哪些不一样? 

1:HTML 标签不能自定义,XML 标签只能自定义;

2:HTML 语法要求不严格;XML 语法要求极其严格,必须是成对标签

3:xml 用来传输和存储数据,HTML 用来展示数据; 

四、元素、属性、注释

4-1、元素(Element):

<book><title>XML 入门</title>
</book>

元素用于包裹信息,有开始和结束标签。

4-2、属性(Attribute):

<book title="XML 入门" price="59.8" />

属性是附加在标签上的键值对,用来表示额外信息

属性的命名规则:

数字、字母、下划线;数字不能开头!

一般建议:数据用子元素,元数据用属性

概念解释举例
数据(Data)你真正关心的业务内容姓名、年龄、价格、标题等
元数据(Metadata)对数据的描述或附加说明,不是数据本身id、类型、单位、语言、版本等

4-3、注释:

<!-- 这是一本书 -->
<book>...</book>

和 HTML 一样,注释用 <!-- -->。 

五、特殊字符使用实体转义

字符实体写法
<&lt;
>&gt;
&&amp;
"&quot;
'&apos;

六、CDATA

在 XML 中使用 <![CDATA[...]]> 是为了处理包含特殊字符或需要保留原始格式的内容

当你想在 XML 中保留“原样文本”,而不想让里面的字符被当作标签或实体解析时,就用 CDATA。

CDATA(不转义内容):

<![CDATA[ 你的原始文本 ]]>

⚠️ 限制:

  1. 不能嵌套 CDATA(你不能在 CDATA 里面再写 <![CDATA[

  2. 不能包含 ]]> 本身,否则解析器会当 CDATA 提前结束

  3. CDATA 是 节点的文本内容,不能用于属性值(属性值必须转义)

示例:文本中有 <,不能直接写

<message>2 < 5</message>     <!-- ❌ 错误写法,会报错 -->
<message>2 &lt; 5</message>  <!-- ✅ 正确,但繁琐 -->

更好的写法:

<message><![CDATA[2 < 5]]></message>

七、DTD / XSD

格式正确的XML(Well Formed)是指XML的格式是正确的,可以被解析器正常读取。

而合法的XML是指,不但XML格式正确,而且它的数据结构可以被DTD或者XSD验证

DTD文档可以指定一系列规则,例如:

  • 根元素必须是book
  • book元素必须包含nameauthor等指定元素
  • isbn元素必须包含属性lang
  • ...

如何验证XML文件的正确性呢?最简单的方式是通过浏览器验证。可以直接把XML文件拖拽到浏览器窗口,如果格式错误,浏览器会报错。 

和结构类似的HTML不同,浏览器对HTML有一定的“容错性”,缺少关闭标签也可以被解析,但XML要求严格的格式,任何没有正确嵌套的标签都会导致错误。

XML是一个技术体系,除了我们经常用到的XML文档本身外,XML还支持:

特性作用举例用途
✅ DTD / XSD验证 XML 结构是否合法校验配置、数据格式
✅ XPath精确查找 XML 节点XML 查询、筛选数据
✅ XSLT转换 XML → HTML、XML、文本等报表生成、网页渲染
✅ DOM / SAX解析 XML 文件(Java 常用)读写 XML 数据文件
✅ JAXBJava 类 ↔ XML 的自动映射配置加载、数据传输

实际上,XML的这些相关技术实现起来非常复杂,在实际应用中很少用到,通常了解一下就可以了。

八、XML 高级特性

总览:XML 的五大高级特性

特性作用举例用途
✅ DTD / XSD验证 XML 结构是否合法校验配置、数据格式
✅ XPath精确查找 XML 节点XML 查询、筛选数据
✅ XSLT转换 XML → HTML、XML、文本等报表生成、网页渲染
✅ DOM / SAX解析 XML 文件(Java 常用)读写 XML 数据文件
✅ JAXBJava 类 ↔ XML 的自动映射配置加载、数据传输

8-1、DTD / XSD:验证 XML 的结构(结构约束)

为什么需要它?

你写了一个 XML 文档,比如:

<person><name>张三</name><age>20</age>
</person>

但你怎么知道:

  • 有没有多写/漏写标签?

  • 类型对不对?

  • 标签顺序是否正确?

就需要用 DTD(Document Type Definition)或 XSD(XML Schema) 来定义**“这份 XML 应该长什么样”**。


1、DTD 示例:

<!DOCTYPE person [<!ELEMENT person (name, age)><!ELEMENT name (#PCDATA)><!ELEMENT age (#PCDATA)>
]>

用于说明:

  • person 标签下有 nameage

  • 内容是文本

2、XSD 示例(更强大,支持类型):

<xs:element name="age" type="xs:integer"/>

XSD 支持:

  • 数字、字符串、日期等类型

  • 可选/必填字段

  • 枚举值、正则表达式


 

8-2、XPath:XML 中的路径语言

类似 HTML 中的 CSS Selector

如果你有这样一份 XML:

<students><student><name>小明</name><age>20</age></student>
</students>

你可以用 XPath 表达式精准查找:

XPath含义返回内容
/students/student/name根节点开始查找 name小明
//name所有叫 name 的元素小明
//student[age>18]年龄大于 18 的学生student 节点

XPath 广泛用于:XML 查询引擎、XSLT 过滤器、Selenium 网页爬虫等


 

8-3、XSLT:XML 转换工具

把一份 XML 转换成另一份 XML、HTML 或纯文本,像是“模板引擎”。

应用场景:

  • 把 XML 转为 HTML 页面(用于新闻站点、商品列表等)

  • 把数据格式从 A 转为 B(跨平台转换)

  • 生成报表、文档

 

示例:把 XML 转成 HTML 列表

原始 XML:

<books><book><title>Java基础</title><price>59.8</price></book>
</books>

XSLT 文件:

<xsl:template match="book"><li><xsl:value-of select="title"/> - ¥<xsl:value-of select="price"/></li>
</xsl:template>

最终生成:<li>Java基础 - ¥59.8</li>


8-4、DOM / SAX:XML 文件解析方式(Java 中常见)

因为XML是一种树形结构的文档,它有两种标准的解析API:

  • DOM:一次性读取XML,并在内存中表示为树形结构;
  • SAX:以流的形式读取XML,使用事件回调。

1、DOM(Document Object Model)

  • 一次性读取整棵 XML 树结构进内存

  • 优点:操作灵活、结构清晰

  • 缺点:大文件占内存高

DOM模型就是把XML结构作为一个树形结构处理,从根节点开始,每个节点都可以包含任意个子节点。 

示例:

<?xml version="1.0" encoding="UTF-8" ?>
<book id="1"><name>Java核心技术</name><author>Cay S. Horstmann</author><isbn lang="CN">1234567</isbn><tags><tag>Java</tag><tag>Network</tag></tags><pubDate/>
</book>

注意到最顶层的document代表XML文档,它是真正的“根”,而<book>虽然是根元素,但它是document的一个子节点。 

 Java提供了DOM API来解析XML,它使用下面的对象来表示XML的内容:

  • Document:代表整个XML文档;
  • Element:代表一个XML元素;
  • Attribute:代表一个元素的某个属性。

使用DOM API解析一个XML文档的代码如下:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc = factory.newDocumentBuilder().parse("file.xml");
Element root = doc.getDocumentElement();

或者:

InputStream input = Main.class.getResourceAsStream("/book.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(input);

DocumentBuilder.parse()用于解析一个XML,它可以接收InputStream,File或者URL,如果解析无误,我们将获得一个Document对象,这个对象代表了整个XML文档的树形结构,需要遍历以便读取指定元素的值: 

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;public class XmlPrinter {public static void main(String[] args) throws Exception {// 1. 加载 XML 文件File file = new File("/Users/wangsi/IdeaProjects/javaSE/src/student.xml");  // 文件路径DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();// 2. 解析为 Document 对象Document document = builder.parse(file);// 3. 获取根节点(Element 是 Node 的子类)Node root = document.getDocumentElement();// 4. 调用你写的递归打印方法printNode(root, 0);}public static void printNode(Node n, int indent) {for (int i = 0; i < indent; i++) {System.out.print(' ');}switch (n.getNodeType()) {case Node.DOCUMENT_NODE:System.out.println("Document: " + n.getNodeName());break;case Node.ELEMENT_NODE:System.out.println("Element: " + n.getNodeName());break;case Node.TEXT_NODE:// 忽略只包含空白的文本节点String text = n.getNodeValue().trim();if (!text.isEmpty()) {System.out.println("Text: " + n.getNodeName() + " = " + text);}break;case Node.ATTRIBUTE_NODE:System.out.println("Attr: " + n.getNodeName() + " = " + n.getNodeValue());break;default:System.out.println("NodeType: " + n.getNodeType() + ", NodeName: " + n.getNodeName());}// 5. 如果是元素,还要打印属性if (n.getNodeType() == Node.ELEMENT_NODE) {NamedNodeMap attrs = n.getAttributes();for (int i = 0; i < attrs.getLength(); i++) {printNode(attrs.item(i), indent + 2);}}// 6. 遍历子节点for (Node child = n.getFirstChild(); child != null; child = child.getNextSibling()) {printNode(child, indent + 2);}}}

 

对于DOM API解析出来的结构,我们从根节点Document出发,可以遍历所有子节点,获取所有元素、属性、文本数据,还可以包括注释,这些节点被统称为Node,每个Node都有自己的Type,根据Type来区分一个Node到底是元素,还是属性,还是文本,等等。

使用DOM API时,如果要读取某个元素的文本,需要访问它的Text类型的子节点,所以使用起来还是比较繁琐的。

 使用DOM解析XML的优点是用起来省事,但它的主要缺点是内存占用太大


2、SAX(Simple API for XML)

  • 事件驱动式解析不存整个树结构,边读边处理

  • 适合大文件或只读操作

SAX是Simple API for XML的缩写,它是一种基于的解析方式,边读取XML边解析,并以事件回调的方式让调用者获取数据。因为是一边读一边解析,所以无论XML有多大,占用的内存都很小。 

SAX解析会触发一系列事件:

  • startDocument:开始读取XML文档;
  • startElement:读取到了一个元素,例如<book>
  • characters:读取到了字符;
  • endElement:读取到了一个结束的元素,例如</book>
  • endDocument:读取XML文档结束。

 如果我们用SAX API解析XML,Java代码如下:

InputStream input = Main.class.getResourceAsStream("/book.xml");
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
saxParser.parse(input, new MyHandler());

关键代码SAXParser.parse()除了需要传入一个InputStream外,还需要传入一个回调对象,这个对象要继承自DefaultHandler:

class MyHandler extends DefaultHandler {public void startDocument() throws SAXException {print("start document");}public void endDocument() throws SAXException {print("end document");}public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {print("start element:", localName, qName);}public void endElement(String uri, String localName, String qName) throws SAXException {print("end element:", localName, qName);}public void characters(char[] ch, int start, int length) throws SAXException {print("characters:", new String(ch, start, length));}public void error(SAXParseException e) throws SAXException {print("error:", e);}void print(Object... objs) {for (Object obj : objs) {System.out.print(obj);System.out.print(" ");}System.out.println();}
}

运行SAX解析代码,可以打印出下面的结果:

start document
start element:  book
characters:start element:  name
characters: Java核心技术
end element:  name
characters:start element:  author
...

DOM 更适合增删查改,SAX 更适合读文件做分析。


8-5、JAXB:Java ↔ XML 映射工具(非常实用!)

JAXB(Java Architecture for XML Binding)可以把 XML 文件自动映射成 Java 对象,或者反过来写入 XML

示例:

Java Bean:

@XmlRootElement(name = "person")
public class Person {public String name;public int age;
}

读取 XML 到对象:

JAXBContext context = JAXBContext.newInstance(Person.class);
Person p = (Person) context.createUnmarshaller().unmarshal(new File("person.xml"));

类似 JSON ↔ Java(Gson、Jackson),但是 XML 的双向转换。


8-6、使用Jackson:Java ↔ XML 映射工具

Jackson 和 JAXB,两者都能实现“XML ↔ Java 对象”的双向转换。

  • Jackson 更通用,支持 JSON 和 XML;
  • JAXB 是专门为 XML 设计的官方标准。
特性JAXBJackson
官方地位Java 官方标准第三方库
XML 支持原生、强大通过扩展模块
JSON 支持❌ 不支持✅ 支持(主打)
默认注解包javax.xml.bind.annotation.*com.fasterxml.jackson.*
是否支持 Schema✅ 可通过 XSD 生成 Java 类❌ 不擅长
Java 版本Java 8 自带,Java 11 需要手动导包全版本支持
在 Spring 中的使用较少用Spring Boot 默认 JSON/XML 工具

前面我们介绍了DOM和SAX两种解析XML的标准接口。但是,无论是DOM还是SAX,使用起来都不直观。

如果能直接从XML文档解析成一个JavaBean,那比DOM或者SAX不知道容易到哪里去了。

一个名叫Jackson的开源的第三方库可以轻松做到XML到JavaBean的转换。我们要使用Jackson,先添加一个Maven的依赖。

<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><version>2.15.3</version> <!-- 用最新版 -->
</dependency>

 Jackson 支持两种方式协同工作:

  1. 使用 XmlMapper

  2. 配合注解,来精细控制 XML ↔ JavaBean 的映射关系

1、 使用 XmlMapper

示例:

InputStream input = Main.class.getResourceAsStream("/book.xml");
JacksonXmlModule module = new JacksonXmlModule();
XmlMapper mapper = new XmlMapper(module);
Book book = mapper.readValue(input, Book.class);
System.out.println(book.id);
System.out.println(book.name);
System.out.println(book.author);
System.out.println(book.isbn);
System.out.println(book.tags);
System.out.println(book.pubDate);

注意到XmlMapper就是我们需要创建的核心对象,可以用readValue(InputStream, Class)直接读取XML并返回一个JavaBean。运行上述代码,就可以直接从Book对象中拿到数据。

2、配合注解,精细控制

示例:

@JacksonXmlRootElement(localName = "Person")
public class Person {@JacksonXmlProperty(localName = "name")private String name;@JacksonXmlProperty(isAttribute = true)private int age;
}
方式你告诉它例子
默认方式靠字段名自动猜XmlMapper.readValue(input, Book.class)
注解方式你明确告诉它 “name 是元素”、“age 是属性”@JacksonXmlProperty(...)

当你要做以下事情时,注解就必须上场了:

场景用法
XML 字段名 和 Java 字段名 不一样@JacksonXmlProperty(localName = "bookName")
要把字段转成属性而不是子标签@JacksonXmlProperty(isAttribute = true)
需要根标签重命名@JacksonXmlRootElement(localName = "Book")
嵌套结构/列表@JacksonXmlElementWrapper(useWrapping = false)

 

3、Spring Boot 默认集成 Jackson

Spring Boot 默认集成 Jackson,自动将 Java 对象 和 JSON 之间进行转换,主要用于:

  • 请求参数(@RequestBody)

  • 响应数据(@ResponseBody / REST 接口)

Spring Boot 使用 Jackson 的核心场景是:

1. 控制器返回对象 → 自动转为 JSON:

@RestController
public class BookController {@GetMapping("/book")public Book getBook() {return new Book("Java入门", "张三");}
}

 访问 /book 时,Spring Boot 自动把 Book 对象转为 JSON:

{"title": "Java入门","author": "张三"
}

2. 接收 JSON 请求体并自动转为 Java 对象:

@PostMapping("/book")
public String addBook(@RequestBody Book book) {return "收到书:" + book.getTitle();
}

如果前端传:

{"title": "Java核心","author": "李四"
}

后端会自动把它转换为 Java 对象。

http://www.lqws.cn/news/514765.html

相关文章:

  • 了解笔记本电脑制造:从品牌到代工厂的全产业链
  • Node.js-fs模块
  • linux内核中的链表实现
  • sentinel与seata组件在微服务中的基本作用
  • 微信点餐小程序—美食物
  • ICML 2025 | 低秩Swish网络:理论突破实现高效逼近,小模型性能媲美大网络
  • CSP - J 400分题单总结(洛谷题号)
  • 通过 HTML 子图和多尺度卷积 BERT 的双向融合实现可解释的恶意 URL 检测
  • xtrabackup 的工作原理 为什么不用停服?
  • Jenkins Pipeline 与 Python 脚本之间使用环境变量通信
  • IDEA高效开发指南:JRebel热部署
  • 设计模式精讲 Day 13:责任链模式(Chain of Responsibility Pattern)
  • 激光束修复手机屏任意层不良区域,实现液晶线路激光修复原理
  • 鸿蒙与h5的交互
  • AR美型SDK,重塑面部美学,开启智能美颜新纪元
  • 微信小程序适配 iPhone 底部导航区域(safe area)的完整指南
  • 【JAVA】idea中打成jar包后报错错误: 找不到或无法加载主类
  • 大学专业科普 | 物联网、自动化和人工智能
  • IO多路复用——Poll底层原理深度分析
  • 深入解析RS485通信:从原理到Linux驱动开发实践
  • DeepSeek在数据分析与科学计算中的革命性应用
  • “易问易视”——让数据分析像聊天一样简单
  • 终止分区表变更操作时误删数据字典缓存导致MySQL崩溃分析
  • 【网站内容安全检测】之2:从网站所有URL页面中提取所有外部及内部域名信息
  • 批量DWG转PDF工具
  • 提供一种在树莓派5上切换模式的思路(本文是面向显示屏配置文件)
  • LVS-DR负载均衡群集深度实践:高性能架构设计与排障指南
  • BUUCTF在线评测-练习场-WebCTF习题[ACTF2020 新生赛]BackupFile1-flag获取、解析
  • 一款实验室创客实验室用的桌面式五轴加工中心
  • 04-html元素列表-表格-表单