XML
概念
xml->可拓展标记语言
- 标记
标记语言(标签语言),用一系列的标签来对数据进行描述
lisi
这就可以表示 lisi是名字(name) - 拓展
用户可以自定义标签
作用
- xml可以作为数据传输的标准(重要)
作为数据的一种传输标准,要考虑可读性、可扩展性、可维护性,并且最好是和语言无关。XML
作为传输数据的标准就比较适合,在上述方面表现都很好。 - xml可以作为配置文件(重要)
很多软件和框架,都会提供XML文件配置的方式,以便可以方便快捷的修改软件或框架的功能 - xml可以持久化数据
可以将数据存到xml文件中,把xml当做一个临时的“数据库”,当然,重要的数据还是要存到真的
数据库中 - xml简化平台变更
在系统更换平台的时候,普通的数据会存在不兼容的问题,但是XML 数据以文本格式存储,这使
得 XML 在不损失数据的情况下,更容易扩展和升级。
xml历史
- 1969年 GML 通用标记语言
用于计算机之间的通信,通信就会传输数据,那么就需要一种数据的规范 - 1985年 SGML 标准通用标记语言
对GML进行完善 - 1993年 HTML 超文本的标记语(HyperText Markup Language)
随着万维网的推广,在SGML的基础上,又出现了HTML语言,用于万维网上的页面展示 - 1998年 XML 可扩展的标记语言(Extensible Markup Language)HTML有不少的缺陷,HTML语言的标记不能自定义,HTML语言的标记本身不能用来描述数据等。
W3C组织在1998年推出了可扩展标记语言XML,最初的本意是用来替代HTML语言的,但是俩种语言还有一定差异的,所以中间出现了一种过渡的语言:XHTML但实际上XML语言已经很难替代HTML语言了,因为HTML语言的使用在整个万维网上使用太广泛了。
XML和HTML的区别
- XML主要是用来描述数据
lisi 描述lisi这个数据是name - HTML主要是用来展示数据
lisi 直接展示数据,不对数据进行描述
xml语法(重点)
文档声明
<?xml version="1.0" encoding="utf-8"?>
这个必须要放在文档的第一行
描述了xml的版本号和所采用的编码
元素
元素,指的是xml中的标记(标签,节点)
lisi
一个xml元素可以包含字母,数字,部分可见字符
元素的规范
- 不能以数字或者部分标点符号开头
<root>
<!-- 正确 -->
<work></work>
<!-- 错误 -->
<,></,>
<1></1>
</root>
- 不能包含空格和特定的几个符号
<root>
<!-- 正确 -->
<work></work>
<!-- 错误 -->
< work></ work>
<,work></,work>
</root>
- 标签必须成对出现,不允许缺少结束标签
<root>
<!-- 正确 -->
<work></work>
<!-- 错误 -->
<work>
</root>
- 根元素有且只有一个
<?xml version="1.0" encoding="UTF-8"?>
<!-- 正确 -->
<root>
</root>
<!-- 错误 -->
<sss>
</sss>
- 大小写敏感
<?xml version="1.0" encoding="UTF-8"?>
<!-- 正确 -->
<root>
<work></work>
<WORK></WORK>
</root>
- 允许多层嵌套但不允许交叉嵌套
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!-- 正确 -->
<a><b></b></a>
<!-- 错误 -->
<a><b></a></b>
</root>
注意:这里的root是根元素
元素可以包含标签体,开始标签和结束标签之间称为标签体
标签中出现空格和换行在xml解析中也会当作标签体进行处理
当然一部分的解析工具栏会自动忽略掉为了代码美观而增加的换行和空格
属性
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!-- 正确 -->
<a b="1" c='2'>
</a>
</root>
其中的b和c就是属性,双引号和单引号之间的数据是对应的属性值,一个标签可以拥有0个或者多个属性
实体
在xml中,一些字符拥有特殊的意义,在xml文档中,是不可以之间使用的
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!-- 正确 -->
<a> > </a>
</root>
如果把字符 “>” 放在 XML 元素中,会发生错误.
浏览器中的错误信息
右键对应的xml文件点击properties,
复制文件地址然后粘贴到浏览器网址栏
这个时候就绪xml中的实体,来代替这个我们所要描述的数据
xml中的实体格式:&实体名;
除了xml中自己提前定义号的实体,我们也可以自己自定义实体
定义的格式
<!DOCTYPE 根元素名称[
<!ENTITY 实体名 实体内容>
]>
例如
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root[
<!ENTITY kk "十元里美">
]>
<root>
<!-- 正确 -->
<a> &kk; </a>
</root>
浏览器结果
当然也可以显示实体,将实体放到<[CDATA[实体]]>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root[
<!ENTITY kk "十元里美">
]>
<root>
<!-- 正确 -->
<a> <![CDATA[&kk;]]></a>
</root>
注释
xml中的注释
<!-- 这是一个注释 -->
注意:
- 注释内容中不要出现 –
- 不要把注释放在标签中间
- 注释不能嵌套
CDATA
在xml中解析器进行解析的内容,称为PCDATA(Parsed CDATA,解析器不会解析的内容,称为CDATA,(Character Data)
例如像之前的实体,当不希望被解析称为实体所代表的内容,而是把实体当作一种数据,这种时候就需要用CDATA
<![CDATA[需要原样输出的字符串]]>
xml和css
这里其实不是很重要,因为一旦加了css样式,那么xml的无法体现描述数据的效果,就会变得和HTML一样变成展示数据
xml文件中导入css文件
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="./NewFile.css" type="text/css?>
<students>
<student>
<name>石原里美</name>
<age>33</age>
</student>
<student>
<name>小十元</name>
<age>13</age>
</student>
</students>
css文件
@charset "UTF-8";
name{
color: red;
font-size: 50px;
}
age{
color: green;
}
此时浏览器展示的结果
而不是原来的
所以css是通常用来给HTML中内容、或者XML中内容进行样式的渲染,这里需要先简单的使用一下,配合XML来渲染需要显示的内容。
了解就行
命名空间
XML文档中的标签,是用户可以自定义的,所以可能在俩个不同的XML文档中,出现相同名字的标签元素。
这时候可以通过前缀来避免这样的问题出现,同时也可以声明这个前缀属于哪个命名空间
<?xml version="1.0" encoding="utf-8"?>
<x:table xmlns:x="http://www.briup.com/XML/ns/x/">
<tr>
<td>hello</td>
<td>world</td>
</tr>
</x:table>
其中x:是前缀
xmlns:x="http://www.briup.com/XML/ns/x/"是命名空间
其实也可以不要前缀,直接定义默认的命名空间:
命名空间的目的,就是为了让这个自定义的标签具有唯一性,不会和别人定义的冲突。
这和Java中定义包名是一样的效果
xml约束
这个其实就是为了用户可以按照我们的要求去定义标签,按照提前定义的规则去编写xml内容
这就要涉及到dtd和Schema。
良构和有效
一个XML文件,如果里面的内容,满足XML的基本语法要求,那么这个XML文件就可以说是良构的。
在XML文件是良构的基础上,如果这个XML文件还通过dtd文件或者Schema文件的约束验证,那么这个
XML文件就可以说是有效的。
我觉得作为一个Java程序员,xml约束这方面的内容了解即可,因为如果用的是IDEA,导入这一块只要有网就可以完成。
其他内容感兴趣可以自行了解
相应大佬的网址
https://blog.csdn.net/sunxing007/article/details/5684265?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
xml解析作业(关于xml解析后期会出教案)
作业
解析一个person.xml
<?xml version="1.0" encoding="UTF-8"?>
<person class="com.briup.day01.Person">
<id>1</id>
<name>石原里美</name>
<desc>向往的光</desc>
</person>
并且用解析的内容创建一个person对象
public class Person {
private int id;
private String name;
private String desc;
public void show() {
System.out.println(this.id+":"+this.name+":"+this.desc);
}
}
答案
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Test {
public static int id;
public static String name;
public static String desc;
public static String className;
//获取xml中的数据
public static void test() throws Exception {
//创建工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
//创建解析对象
DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
//解析文件,获取document
Document document = documentBuilder.parse("src./Person.xml");
//获取根元素
Element root = document.getDocumentElement();
//获取根节点中的属性
System.out.println(root.getNodeName());
NamedNodeMap map = root.getAttributes();
for (int i = 0; i < map.getLength(); i++) {
Node item = map.item(i);
if("class".equals(item.getNodeName())) {
className = item.getNodeValue();
}
}
//获取其子节点
NodeList nodes = root.getChildNodes();
//循环所有节点
for (int i = 0; i < nodes.getLength(); i++) {
//获取每个节点
Node node = nodes.item(i);
switch (node.getNodeType()) {
//获取文本内容
case Node.TEXT_NODE:
System.out.println(node.getTextContent());
break;
//获取元素节点
case Node.ELEMENT_NODE:
System.out.println(node.getNodeName()+"="+node.getTextContent());
switch (node.getNodeName()) {
case "id":
id = Integer.parseInt(node.getTextContent());
break;
case "name":
name = node.getTextContent();
case "desc":
desc = node.getTextContent();
default:
break;
}
//获取元素节点中的所有的属性
NamedNodeMap attributes = node.getAttributes();
//循环遍历每一个具体的属性
for (int j = 0; j < attributes.getLength(); j++) {
//将对应节点的属性输出
Node attr = attributes.item(j);
System.out.println(attr.getNodeName()+"="+attr.getNodeValue());
}
//获取当前节点下面的字节点
NodeList childNodes = node.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++) {
Node item = childNodes.item(j);
if(item.getNodeType() == Node.ELEMENT_NODE) {
System.out.println(item.getNodeName()+"="+item.getTextContent());
}
}
break;
default:
throw new RuntimeException("意外节点类型:"+node);
}
}
}
public static void main(String[] args) throws Exception {
Test.test();
Class<?> c = Class.forName(className);
Person person = (Person) c.newInstance();
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
switch (field.getName()) {
case "id":
field.set(person, Test.id);
break;
case "name":
field.set(person, Test.name);
break;
case "desc":
field.set(person, Test.desc);
break;
default:
break;
}
}
Method method = c.getMethod("show");
method.invoke(person);
}
}