学习笔记:javaEE基础1 XML

来源于从网页搭建入门Java Web

这里是xml专场!


声明

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

转义

  • 实体引用

    • &lt; <
    • &gt; >
    • &amp; &
    • &apos; '
    • &quot; "
  • CDATA标签

<![CDATA[ .... ]]>

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<lesson>
<content>
<![CDATA[
<html><body>Test</body></html>
]]>
</content>
</lesson>

语义约束

DTD

  • 数量限制
    • <!ELEMENT hr (employee)> 只能1个
    • <!ELEMENT hr (employee+)> 最少1个
    • <!ELEMENT hr (employee*)> 最少0个
    • <!ELEMENT hr (employee?)> 最多一个
  • 引入DTD文件
    • <!DOCTYPE 根节点 SYSTEM ”路径“> system代表来自本地
  • 属性设置
    • <!ATTLIST employee no CDATA "">
  • 节点所包括的值设置
    • <!ELEMENT employee (name, age)>
  • 变量声明
    • <!ELEMENT age (#PCDATA)>
1
2
3
4
5
6
7
8
9
10
11
<!-- DTD文档 -->
<?xml version="1.0" encoding="UTF-8"?>
<!--s声明子节点的个数-->
<!ELEMENT hr (employee+)>
<!--声明变量-->
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!--声明节点所包含的值-->
<!ELEMENT employee (name, age)>
<!--声明属性-->
<!ATTLIST employee no CDATA "">

1
2
3
4
5
6
7
8
9
<!-- 对应的xml文件 -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hr SYSTEM "hr.dtd">
<hr>
<employee no="12">
<name>aaaa</name>
<age>12</age>
</employee>
</hr>

XML Schema

W3C标准规范 .xsd 比较常用的,但是结构比较复

注意:如果不添加命名空间的话Intellij IDEA会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!-- XML Schema,文件名为hr.xsd,在第二段代码开头需要引入 -->
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3school.com.cn"
xmlns="http://www.w3school.com.cn"
elementFormDefault="qualified"
>
<xs:element name="hr">
<!-- 复杂节点声明 -->
<xs:complexType>
<xs:sequence>
<xs:element name="employee" minOccurs="1" maxOccurs="999">
<xs:complexType>
<!-- 这样子声明的话写xml时顺序不能搞错 -->
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<!-- 对类型进行一些条件限制 -->
<xs:element name="age">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="18"/>
<xs:maxInclusive value="60"/>
</xs:restriction>
</xs:simpleType>
</xs:element>

<!-- 可以进行嵌套 -->
<xs:element name="department">
<xs:complexType>
<xs:sequence>
<xs:element name="dname" type="xs:string"/>
<xs:element name="local" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<!-- 声明标签 -->
<xs:attribute type="xs:string" name="id" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

对应的xml数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!-- hr.xsd.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<hr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3school.com.cn"
xsi:schemaLocation="http://www.w3school.com.cn hr.xsd">
<employee id="122">
<name>aaaa</name>
<age>55</age>
<department>
<dname>研发部</dname>
<local>xx大厦200</local>
</department>
</employee>
<employee id="123">
<name>bbb</name>
<age>25</age>
<department>
<dname>市场部</dname>
<local>xx大厦201</local>
</department>
</employee>
<employee id="3322">
<name>2233</name>
<age>45</age>
<department>
<dname>运营部</dname>
<local>XX大厦</local>
</department>
</employee>
</hr>

使用dom4j读写xml

对上面的 hr.xsd.xml 进行操作,没什么好说的,就是那个库把xml文件读入进内存封装成Document,然后你就可以像js操作dom一样对它进行操作了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public class App {
private String filePath = "xml/hr.xsd.xml";

// 读文件
public void readXml() {
// 解析,生成树结构
SAXReader reader = new SAXReader();
// 生成document
Document document = null;
try {
document = reader.read(filePath);
// 获取根节点
Element root = document.getRootElement();
List<Element> employees = root.elements("employee");

for (Element employee : employees) {
Element name = employee.element("name");
String empName = name.getText();
System.out.print(
empName + " " + employee.elementText("age") + " "
+ employee.attribute("id").getText() + " " + employee.element("department").elementText("dname"));

System.out.println();
}
} catch (DocumentException e) {
e.printStackTrace();
}
}

// 写文件
public void writeXml() {
try {
SAXReader reader = new SAXReader();
Document document = null;
document = reader.read(filePath);

Element root = document.getRootElement();
Element employee = root.addElement("employee");
employee.addElement("name").setText("2233");
employee.addElement("age").setText("45");
employee.addAttribute("id", "3322");
Element department = employee.addElement("department");
department.addElement("dname").setText("运营部");
department.addElement("local").setText("XX大厦");

Writer writer = new OutputStreamWriter(new FileOutputStream(this.filePath), "UTF-8");
document.write(writer);
writer.close();

} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
App app = new App();
app.writeXml();
app.readXml();
}

}

使用xpath解析xml

关于xpath的部分语法如下

这里需要使用到dom4j和jaxen两个java包,在解析的时候需要注入,如果xml使用了命名空间,需要对其进行额外处理,详见此链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class XPathTester {

public void xpathTest(String xpathStr) {
String file = "xml/hr.xsd.xml";
SAXReader reader = new SAXReader();
// 对命名空间进行处理
Map map = new HashMap();
map.put("xs","http://www.w3school.com.cn");
try {
Document document = reader.read(file);
XPath x = document.createXPath(xpathStr);
x.setNamespaceURIs(map);
List<Node> nodes = x.selectNodes(document);
for (Node node: nodes) {
Element emp = (Element)node;
System.out.println(emp.elementText("name") + " " + emp.elementText("age"));
}
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
XPathTester tester = new XPathTester();
// 使用xpath
tester.xpathTest("//xs:employee");
System.out.println("======");
tester.xpathTest("//xs:employee[xs:age<40]");
System.out.println("======");
tester.xpathTest("//xs:employee[position()<3]");
System.out.println("======");
tester.xpathTest("//xs:employee[last()]");
System.out.println("======");
tester.xpathTest("//xs:employee[@id=3322]");

}
}