XML

XML概述

xml,extend markup language,可扩展标记语言。
html语言的问题(非常松散):
1)html的标签不分大小写 。
2)html的标签可以不匹配。

xml语法比html语法更加严谨:
1)xml的标签区分大小写的
2)xml的标签必须匹配

xml的作用:
1)描述带关系的数据结构,所以可以作为软件的配置文件
2)存储数据,所以可以作为“小型的数据库”
html
名称: 超文本标记语言
标签的定义: w3c固定的标签
作用: 负责网页的结构(展示)
xml
名称: 可扩展标记语言
标签的定义: 可以让开发者自定定义(扩展)
作用: (1)软件的配置文件(2)小型的“数据库”
1)软件的配置文件
.properties文件。格式: key=value key=value 没有的关系,不能描述数据的关系
xml文件格式:( xml可以描述包含与被包含)

	<student>
		<name>张三</name>
	</student>
	<student>
		<name>李四</name>
	</student>

(1) 作为软件的配置(最常见)
struts2, spring, hibernate 软件的半成品 + xml文件 tomcat服务器 ->xml文件

(2)“小型数据库”
存储到mysql数据库的数据,同样也可以存储到xml文件

XML语法
数据分类:字符(字节+编码),字节。 编码过程:字符->字节(查码表) 解码过程:字节->字符 作用: 规定如何编写一个合法的xml文件。 .xml

xml文档声明
第一行: <?xml version="1.0" encoding="GBK" standalone="yes"?>
version: 代表xml文件的版本 通常用1.0就可以了
encoding: 编码。解析器解析xml文件时的编码(中文).默认值是UTF-8
(浏览器内置了xml解析器,所以浏览器可以解析xml文件)

涉及xml文件的编码问题:
1)保存xml文件时的编码
2)文档声明的encoding
3)浏览器的设置编码

三个编码必须保持一致,这样才不会出现中文乱码问题!!!

standalone: 是否引用了文件

2)注释

<!-- xml注释 -->

3)标签,属性
命名规则:
区分大小写,例如,<P><p>是两个不同的标签。
不能以数字开头。
不能以xml(或XML、或Xml 等)开头。(执行是可以,是xml名称是xml语法的保留关键 词)
中间和开头不能包含空格。
名称中间不能包含冒号(:)。(冒号是名称空间的保留字符,不能用。比如:itcast:)

标签:
在一个xml文件中,有且仅有一个根标签
属性:
1)可以有多个属性,每个属性以name="值"形式存在
2)属性值必须使用引号包含,要么是单引号,要么是双引号,不能单双混用
3) 在同一个标签内不能出现两个同名属性

4)转义字符
< &lt;
> &gt;
空格 &nbsp;
&quot;
&apos;
5)CDATA
语法:<![CDATA[ 内容 ]]>
作用:可以同时对CDATA的内容进行转义。
6)处理指令
作为html作用使用。
可以通知解析器忽略标签名内容,只保留标签体内容。
<?xml-stylesheet type="text/css" href="xmlcss.css"?>
在xmlcss.css中选择元素,设置样式。

XML约束之dtd

什么是良好的XML?
符合W3C制定的语法规范(也就是上面所提到的所有XML语法),我们就说这个XML是良好的XML。
什么是有效的XML?
符合约束规则,通过了用户自定义的DTD或者Schema校验的约束规则,我们就说这个XML是有效的XML。
使用(dtd约束和schema约束)约束xml,让其成为有效的xml。
dtd约束,语法比较简单,功能不够丰富(数据类型比较单一)struts2和hierbnate的xml约束就是使用dtd约束。
schema约束,为了替代dtd约束,语法相对强大,功能比较丰富(数据类型丰富,支持名称空间)spring的xml使用的是schema约束,tomcat的web.xml使用schema约束。
dtd约束
知识点链接:https://www.runoob.com/dtd/dtd-intro.html
dtd约束的导入方式
(1).内部导入
特点:dtd内容和xml内容放在一个文件。
(2).外部导入
本地外部导入:dtd文件保存在本地文件系统中

<!DOCTYPE 根元素 SYSTEM "文件名">

网络外部导入:dtd文件保存在互联网上

<!DOCTYPE 文档根结点 PUBLIC "DTD名称" "DTD文件的URL">

dtd语法
在一个 DTD 中,元素通过元素声明来进行声明。
声明一个元素
在 DTD 中,XML 元素通过元素声明来进行声明。元素声明使用下面的语法:

<!ELEMENT 元素名 类别>或<!ELEMENT 元素名 (元素内容)>

类别:(粗略控制,不想schema那么细致)
EMPTY:空元素

<!ELEMENT element-name EMPTY>

实例:

<!ELEMENT br EMPTY>

XML example:

<br />

PCDTAT:普通字符串(包括空,不包含子元素)

<!ELEMENT element-name (#PCDATA)>

实例:

<!ELEMENT from (#PCDATA)>

ANY:任意内容(包含子元素)

<!ELEMENT element-name ANY>

实例:

<!ELEMENT note ANY>

元素内容
顺序问题:(子元素1,子元素2…)一定从左到右依次出现,否则违反约束。
数量问题:
子元素1:有且仅出现一次。
子元素1+:至少出现一次。
子元素1?:出现0或1次。
子元素1*:出现0或多次。
约束属性:

在 DTD 中,属性通过 ATTLIST 声明来进行声明。
声明属性
属性声明使用下列语法:

<!ATTLIST element-name attribute-name attribute-type attribute-value>
DTD 实例:
<!ATTLIST payment type CDATA "check">
XML 实例:
<payment type="check" />
<!ATTLIST 元素名称 属性名称 属性类型 默认值>

默认值:控制属性是否必须
#REQUIRED 属性值是必需的
#IMPLIED 属性不是必需的
#FIXED value 属性值是固定的(可以不写,一旦写了只能写固定值)
属性类型:

CDATA	值为字符数据 (character data,”001“)
(en1|en2|..)	此值是枚举列表中的一个值
ID	值为唯一的 id
IDREF	值为另外一个元素的 id
IDREFS	值为其他 id 的列表
NMTOKEN	值为合法的 XML 名称
NMTOKENS	值为合法的 XML 名称的列表
ENTITY	值是一个实体
ENTITIES	值是一个实体列表
NOTATION	此值是符号的名称
xml:	值是一个预定义的 XML 值
XML解析之DOM解析

xml解析:使用java代码去操作(包括改写)xml文件。
xml解析方式:
DOM解析:
XML DOM原理:xml文档被封装成不同的对象,通过这些对象操作xml文档。把xml文件封装成不同的对象(Document,Element,Attr,Text,Comment),通过对象操作xml文件。
特点:一次性把整个xml文档读入内存,然后组建成DOM树。占用比较大的内存。不太适合读大的文件,容易内存溢出。
面向对象编程方式。
SAX解析:
解析原理:读取一点,解析一点。占用内存非常小。适合读大文件。
基于事件驱动的。
DOM解析工具:
jaxp:sun公司的标准(老产品)。
jdom:开源组织的产品,在jaxp之上封装。
dom4j:是jdom的子产品,在jdom之上封装(更流行)。struts2内部使用的dom4j解析xml配置文件
iaxp工具的使用:
按照DOM原理使用jaxp解析xml文件
jaxp的api在jdk中 org.w3c.dom.*
读取开发步骤:
1.创建DocumentBuilderFactory实例
2.通过DocumentBuilderFactory实例创建DocumentBuilder
3.通过DocumentBuilder的parse方法读取xml文件,返回一个Document对象。
常用方法:
getElementsByTagName() 根据标签名查元素
getElementById()根据id查元素
getAttribute(“name”)根据属性查元素
getTextContent()根据文本内容查元素
NodeList:
getLength()获取节点的长度
item(index)根据下标找节点

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package gz.itcast.a_jaxp;
//目标:jaxp如何读取xml文件
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;

public class DOM1 {
    public DOM1() {
    }

    public static void main(String[] args) throws Exception {
        //创建DocumentBuilderFactory实例
        // Ctrl+2 松开 l
        DocumentBuilderFactory factroy = DocumentBuilderFactory.newInstance();
        //通过DocumentBuilderFactory实例创建DocumentBuilder
        DocumentBuilder builder = factroy.newDocumentBuilder();
        //通过DocumentBuilder的parse方法读取xml文件,返回一个Document对象。
        Document doc = builder.parse("src/Locale.xml");
        System.out.println(doc);
    }
}

修改xml步骤
1.创建TransformerFactory实例。
2.通过TransformerFactory实例创建Transformer。
3.通过Transformer的transfer方法把Document写出xml文件。
createElement(“name”)创建元素
setAttribute(“name”,“value”)创建或修改元素的属性
removeAttribute(“name”)删除属性
setTextContent(“内容”)设置文本内容
案例:

package gz.itcast.a_jaxp;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DOM2 {
    public DOM2() {
    }

    public static void main(String[] args) throws Exception {
        //读取xml文件
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse("src/Locale.xml");
        test4(doc);
    }
    //遍历所有节点
    public static void test1(Document doc) {
        //得到根节点(Location)
        Node root = doc.getElementsByTagName("Location").item(0);
        getChildNodes(root);
    }
     //递归遍历子节点(只需要看元素节点 元素的节点类型Node.ELEMENT_NODE=1)
    public static void getChildNodes(Node node) {
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            System.out.println(node.getNodeName());
        }
        //得到当前节点的所有子节点
        NodeList nList = node.getChildNodes();
        //遍历
        for(int i = 0; i < nList.getLength(); ++i) {
            //得到每一个节点
            Node n = nList.item(i);
            //递归调用getChildNodes(),为了查询当前节点的子节点。
            getChildNodes(n);
        }

    }
    //查询某个节点 1.找“东城”的所在节点(City) 2.得到“东城”的Name属性值和Code属性值 3.得到“延庆”
    public static void test2(Document doc) {
        //找“东城”的所在节点(City)
        Element sELem = (Element)doc.getElementsByTagName("State").item(0);
        //只找当前State下的City
        Element cElem = (Element)sELem.getElementsByTagName("City").item(0);
        //得到“东城”的Name属性值和Code属性值
        System.out.println(cElem.getNodeName());
        System.out.println(cElem.getAttribute("Name"));
        System.out.println(cElem.getAttribute("Code"));
        //得到“延庆”
        NodeList nl = sELem.getElementsByTagName("City");
        int len = nl.getLength();
        Element elem = (Element)sELem.getElementsByTagName("City").item(len - 1);
        System.out.println(elem.getTextContent());
    }
    //修改节点 1.添加一个新的“State” 2.在新的“State”增加Name属性,“广东”,Code为“13” 3.在新的“State”添加一个新的“City” 4.新的“City”文本设置为广州
    public static void test3(Document doc) throws Exception {
        //添加一个新的“State”
        Element newElem = doc.createElement("State");
        //在新的“State”增加Name属性,“广东”,Code为“13”
        newElem.setAttribute("Name", "广东");
        newElem.setAttribute("Code", "13");
        //在新的“State”添加一个新的“City”
        Element cityElem = doc.createElement("City");
        //新的“City”文本设置为广州
        cityElem.setTextContent("广州");
        newElem.appendChild(cityElem);

        Node root = doc.getElementsByTagName("Location").item(0);
        root.appendChild(newElem);
        //1.创建TransformerFactory实例。
        TransformerFactory factory = TransformerFactory.newInstance();
        //2.通过TransformerFactory实例创建Transformer。
        Transformer ts = factory.newTransformer();
        //3.通过Transformer的transfer方法把Document写出xml文件。
        ts.transform(new DOMSource(doc), new StreamResult("src/Locale.xml"));
    }
    //删除节点 1.删除“Name="滨海新区"” 2.删除“<City Name="津南" Code="12"/>”
    public static void test4(Document doc) throws Exception {
        //删除“Name="滨海新区"”
        //得到所在元素
        Element sElem = (Element)doc.getElementsByTagName("State").item(1);
        Element cElem = (Element)sElem.getElementsByTagName("City").item(6);
        //删除Name属性
        cElem.removeAttribute("Name");
        //删除“<City Name="津南" Code="12"/>”
        Element cElem2 = (Element)sElem.getElementsByTagName("City").item(9);
        sElem.removeChild(cElem2);
        //1.创建TransformerFactory实例。
        TransformerFactory factory = TransformerFactory.newInstance();
        //2.通过TransformerFactory实例创建Transformer。
        Transformer ts = factory.newTransformer();
        //3.通过Transformer的transfer方法把Document写出xml文件。
        ts.transform(new DOMSource(doc), new StreamResult("src/Locale.xml"));
    }
}


Locale.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Location>
    <State Code="11" Name="北京">
      <City Code="1" Name="东城"/>
      <City Code="2" Name="西城"/>
      <City Code="5" Name="朝阳"/>
      <City Code="6" Name="丰台"/>
      <City Code="7" Name="石景山"/>
      <City Code="8" Name="海淀"/>
      <City Code="9" Name="门头沟"/>
      <City Code="11" Name="房山"/>
      <City Code="12" Name="通州"/>
      <City Code="13" Name="顺义"/>
      <City Code="21" Name="昌平"/>
      <City Code="24" Name="大兴"/>
      <City Code="26" Name="平谷"/>
      <City Code="27" Name="怀柔"/>
      <City Code="28" Name="密云"/>
      <City>延庆</City>
    </State>
    <State Code="12" Name="天津">
      <City Code="1" Name="和平"/>
      <City Code="2" Name="河东"/>
      <City Code="3" Name="河西"/>
      <City Code="4" Name="南开"/>
      <City Code="5" Name="河北"/>
      <City Code="6" Name="红桥"/>
      <City Code="26" Nmae="滨海新区"/>
      <City Code="10" Name="东丽"/>
      <City Code="11" Name="西青"/>
      <City Code="12" Name="津南"/>
      <City Code="13" Name="北辰"/>
      <City Code="21" Name="宁河"/>
      <City Code="22" Name="武清"/>
      <City Code="23" Name="静海"/>
      <City Code="24" Name="宝坻"/>
      <City Code="25" Name="蓟县"/>
    </State>
</Location>

修改后的文件:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><Location>
    <State Code="11" Name="北京">
      <City Code="1" Name="东城"/>
      <City Code="2" Name="西城"/>
      <City Code="5" Name="朝阳"/>
      <City Code="6" Name="丰台"/>
      <City Code="7" Name="石景山"/>
      <City Code="8" Name="海淀"/>
      <City Code="9" Name="门头沟"/>
      <City Code="11" Name="房山"/>
      <City Code="12" Name="通州"/>
      <City Code="13" Name="顺义"/>
      <City Code="21" Name="昌平"/>
      <City Code="24" Name="大兴"/>
      <City Code="26" Name="平谷"/>
      <City Code="27" Name="怀柔"/>
      <City Code="28" Name="密云"/>
      <City>延庆</City>
    </State>
    <State Code="12" Name="天津">
      <City Code="1" Name="和平"/>
      <City Code="2" Name="河东"/>
      <City Code="3" Name="河西"/>
      <City Code="4" Name="南开"/>
      <City Code="5" Name="河北"/>
      <City Code="6" Name="红桥"/>
      <City Code="26"/>
      <City Code="10" Name="东丽"/>
      <City Code="11" Name="西青"/>
      
      <City Code="13" Name="北辰"/>
      <City Code="21" Name="宁河"/>
      <City Code="22" Name="武清"/>
      <City Code="23" Name="静海"/>
      <City Code="24" Name="宝坻"/>
      <City Code="25" Name="蓟县"/>
    </State>
    <State Code="13" Name="广东"><City>广州</City></State></Location>

jaxp核心dom解析的api:

读取xml文件:
1)DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
2)DocumentBuilder builder = factory.newDocumentBuilder();
3) Document doc = builder.parse(“xml路径”);

写出xml文件:
1) TransformerFactory factory = TransformerFactory.newInstance();
2) Transformer ts = factory.newTransformer();
3) ts.transform(new DOMSource(document), new StreamResult(“xml路径”));
把哪个对象放到哪里去

查询:
document.getElementsByTagName(“name”) 读当前文档下的子元素
document.getElementById(“id”)
element.getElementsByTagName(“name”) 读当前元素下的子元素
element.getAttribute(“name”); 读取属性
element.getTextContent() 读取文本

创建或修改:
document.createElement(“name”); 创建元素
element.setAttribute(“name”,“value”) 创建或修改属性
element.setTextContent(“value”) 修改元素的文本内容

插入和删除:
element.appendChild(element) 把元素放入指定元素的子元素下
element.removeChild(element) 把元素从指定元素的子元素下删除
element.removeAttribute(“name”) 删除某个元素内的属性

jaxp的小练习(必须练习)
成绩管理系统设计(简单分层思想):

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值