<!doctype html>
<html lang="en">
<head>
<title>day06</title>
<meta name ="day06" charset="UTF-8">
</head>
<body>
<pre>
1、schema约束
*DTD语法:<!ELEMENT 元素名称 约束>
*schema符合xml的语法,xml语句
*一个xml中可以有多个schema类型,多个schema使用名称空间区别
*dtd里面有CDATA类型,但是在schema里面可以支持更多的数据类型
-比如 年龄 只能是数字 在schema可以直接定义整数数据类型
*schema语法更加复杂,schema目前不能替代dtd
2、schema快速入门
*创建一个schema文件,后缀.xsd
*schema文件里面
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.itcast.cn/20180802"
elementFormDefault="qualified">
</schema>
-表示当前xml文件是一个约束文件
-使用schema约束文件,直接通过这个地址引入约束文件
-elementFormDefault="qualified"> 合格的
*在xml引入schema文件
<person xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.itcast.cn/20180802" xsd:schemaLocation="http://www.itcast.cn/20180802 PersonXMLSchema.xsd">
</person>
-通过有前缀的名称空间区别xmlns 和 targetNamespace
-表示xml是一个被约束文件
-是约束文档里面 targetNamespace
-targetNamespace 空格 约束文档的路径
*元素约束:
-简单元素:
<element name="标记名称" type="简单数据类型"/>
-复杂元素:
<element name="标签名称">
<complexType>
//下列两个子标记择其一
<sequence>
<element ref="子标记名称1"/>//顺序不可颠倒
<element ref="子标记名称2"/>
<element ref="子标记名称3"/>
</sequence>
<all maxOccurs="unbounded" minOccurs="1">//
<element ref="子标记名称1"/>//顺序随便
<element ref="子标记名称2"/>
<element ref="子标记名称3"/>
</all>
<choice>
<element ref="子标记名称1"/>//只能出现其中的一个
<element ref="子标记名称2"/>
<element ref="子标记名称3"/>
</chioce>
<any>
//任意
</any>
</complexType>
</element>
<element name="子标记名称1" type="数据类型">
<element name="子标记名称2" type="数据类型">
<element name="子标记名称3" type="数据类型">
-复杂元素
//顺序出现,简单元素直接写在sequence里面
<element name="标签名称">
<complexType>
<sequence>
<element name="子标记名称1" type="数据类型"/>
<element name="子标记名称1" type="数据类型"/>
</sequence>
</complexType>
</element>
*属性约束
-<xsd:attribute name="属性名称" type="基本数据类型" use="条件"/>
--use取值:required optional fixed default
--注:attribute必须在复杂元素中使用
-复杂元素
--attribute只要放在复杂元素内即可
<element name="标签名称">
<complexType>
<attribute name="属性名称" type="属性类型" use="条件"/>
<attribute name="name" type="string" use="required"/>
</complexType>
</element>
*xml schema模式的验证
步骤:
File xsdfile = new File("schema.xsd");
File xmlfile = new File("example.xml");
//得到SchemaFactory对象
SchemaFactory schemafactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
//创建Schema对象
Schema schmea = schemafactory.newInstance(xsdfile);
//得到验证器
Validator validator = schema.newValidator();
//验证器先调用方法
validator.setErrorHandler(errorHander);
//在调用方法验证xml文件是否遵守了xmlschema模式
validator.validate(new StreamSource(xmlfile));
3、sax解析的原理
*SAX方式:事件驱动,边读边解析
*在javax.xml.parsersx包里面
-SAXParser:此类的实例可以通过SAXParserFactory.newInstance()对象的方法获取
SAXParser的方法parse(File f , DefaultHandler dh)
--两个参数:xml路径和事件处理器
-SAXParserFactory实例可以通过SAXParserFactory.newInstance()获取
*画图分析一下sax执行过程
-当解析到开始标签时候,自动执行startElement
-当解析到结束标签时候,自动执行endElement
-当解析到文本时候,自动执行characters
4、使用jaxp的sax方式解析xml
*sax方式不能实现增删改操作,只能做查询操作
*打印出整个文档
*执行parse方法,第一个参数是xml路径,第二个参数是事件处理器
-创建一个类,继承事件处理器的类
-重写里面的方法
*案例:
-要求打印所有的name元素的值
--定义一个成员变量 flag =false;
--判断开始方法是否是name元素,如果是fla=true
--如果flag值是true,在characters方法里面打印内容
--当执行到结束标签时候,那flag值设置成false
-获取第一个name的值
--定义一个成员变量index=0;
--在结束开始标签的方法后index++;
--打印判断现在是否index==1;
5、dom4j解析xml
*dom4j是一个组织,针对xml解析,提供解析器dom4j
*dom4j不是javase的不成部分,想要使用需要导入jar包
-新建lib文件夹,复制进来,右键build path 奶瓶图案即可
*得到document
SAXReader reader = new SAXReader();
Document document = reader.read(url);
*document的父接口是Node
-如果在document里面找不到方法,去父接口里面找
-Element的父接口也是Node
*方法
一.Document对象相关
1.读取XML文件,获得document对象.
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
2.解析XML形式的文本,得到document对象.
String text = "<members></members>";
Document document = DocumentHelper.parseText(text);
3.主动创建document对象.
Document document = DocumentHelper.createDocument();
Element root = document.addElement("members");// 创建根节点
二.节点相关
1.获取文档的根节点.
Element rootElm = document.getRootElement();
2.取得某节点的单个子节点.
Element memberElm=root.element("member");// "member"是节点名
3.取得节点的文字
String text=memberElm.getText();
也可以用:
String text=root.elementText("name");这个是取得根节点下的name字节点的文字.
4.取得某节点下名为"member"的所有字节点并进行遍历.
List nodes = rootElm.elements("member");
for (Iterator it = nodes.iterator(); it.hasNext();) {
Element elm = (Element) it.next();
// do something
}
5.对某节点下的所有子节点进行遍历.
for(Iterator it=root.elementIterator();it.hasNext();){
Element element = (Element) it.next();
// do something
}
6.在某节点下添加子节点.
Element ageElm = newMemberElm.addElement("age");
7.设置节点文字.
ageElm.setText("29");
8.删除某节点.
parentElm.remove(childElm);// childElm是待删除的节点,parentElm是其父节点
三.属性相关.
1.取得某节点下的某属性
Element root=document.getRootElement();
Attribute attribute=root.attribute("size");// 属性名name
2.取得属性的文字
String text=attribute.getText();
也可以用:
String text2=root.element("name").attributeValue("firstname");这个是取得根节点下name字节点的属性firstname的值.
3.遍历某节点的所有属性
Element root=document.getRootElement();
for(Iterator it=root.attributeIterator();it.hasNext();){
Attribute attribute = (Attribute) it.next();
String text=attribute.getText();
System.out.println(text);
}
4.设置某节点的属性和文字.
newMemberElm.addAttribute("name", "sitinspring");
5.设置属性的文字
Attribute attribute=root.attribute("name");
attribute.setText("sitinspring");
6.删除某属性
Attribute attribute=root.attribute("size");// 属性名name
root.remove(attribute);
四.将文档写入XML文件.
1.文档中全为英文,不设置编码,直接写入的形式.
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
writer.write(document);
writer.close();
2.文档中含有中文,设置格式写入的形式.
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("GBK"); // 指定XML编码
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"),format);
writer.write(document);
writer.close();
3、带格式写回xml文件.
/构造函数参数,回写操作
FileOutputStream file = new FileOutputStream("src/test.xml");
OutputFormat format = OutputFormat.createPrettyPrint();//漂亮格式
//OutputFormat format = OutputFormat.createCompactFormat();//紧凑格式
//回写xml
XMLWriter xmlWriter = new XMLWriter(file,format);
xmlWriter.write(document);
xmlWriter.close();
五.字符串与XML的转换
1.将字符串转化为XML
String text = "<members> <member>sitinspring</member> </members>";
Document document = DocumentHelper.parseText(text);
2.将文档或节点的XML转化为字符串.
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
Element root=document.getRootElement();
String docXmlText=document.asXML();
String rootXmlText=root.asXML();
Element memberElm=root.element("member");
String memberXmlText=memberElm.asXML();
六.使用XPath快速找到节点.
*可以直接获取某个元素
-第一种形式
/AAA/BBB/DDD:表示一层一层的,得到AAA下面的BBB下面的DDD
-第二种形式
//BBB:表示和这个名称相同,就可以都得到
-第三种形式
//*:所有的元素
-第四种形式
/AAA/BBB[1]表示获取AAA下面的 第一个BBB元素
/AAA/BBB[last()]表示获取AAA下面的 最后一个BBB元素
-第五种形式
//@id表示获取带有id属性的所有元素
//BBB[@id]表示获取BBB下面的所有带id属性的元素
-第六种形式
//BBB[@id="b1"]表示获取BBB下面带有id属性且值等于b1的元素
*在dom4j里面提供两种方法,用来支持xpath
-selectNodes("xpath表达式") :用来获取多个节点
-selectSingleNode("xpath表达式"):获取一个节点
*代码演示
-SAX解析
--主函数
public static void main(String[] args) throws Exception {
//创建SAXParserFactory对象
SAXParserFactory factory = SAXParserFactory.newInstance();
//创建SAXParser对象
SAXParser saxParser = factory.newSAXParser();
//EventHandler对象 事件处理器
EventHandler eventHandler = new EventHandler();
//开始解析xml
saxParser.parse("src/person.xml",eventHandler);
System.out.println("事件处理了:"+eventHandler.count+"个事件");
}
--类EventHandler
public class EventHandler extends DefaultHandler{
int count = 0;
int index = 0;
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
super.startDocument();
System.out.println("开始解析xml文件");
count++;
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
super.endDocument();
System.out.println("解析过程结束");
count++;
}
boolean flag = false;
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if("name".equals(qName))
{
flag= true;
count++;
index++;
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
if("name".equals(qName))
{
flag = false;
count++;
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
if(flag == true && index == 2)
{
System.out.println(new String(ch,start,length));
count++;
}
}
-Dom4j解析
//在特定的位置添加元素
public static void appointLocation() throws Exception{
//创建解析器
SAXReader saxReader = new SAXReader();
//获取document对象
Document document = saxReader.read("src/test.xml");
//获取根节点
Element root = document.getRootElement();
//获取第一个p
Element p = root.element("p");
//获取p下面所有的元素
List<Element> list = p.elements();
//创建元素
Element school = DocumentHelper.createElement("school");
//创建文本
school.setText("ayit");
list.add(1, school);
//回写操作
toXml(document);
}
//回写操作
public static void toXml(Document document) throws Exception
{
//两个参数
FileOutputStream out = new FileOutputStream("src/test.xml");
//格式
OutputFormat format = OutputFormat.createPrettyPrint();
//创建SAXWriter对象
XMLWriter xmlWriter = new XMLWriter(out,format);
xmlWriter.write(document);
xmlWriter.close();
}
//遍历ayit下面所有子节点并添加节点
public static void addElement() throws Exception
{
//创建解析器
SAXReader saxReader = new SAXReader();
//获取Document对象
Document document = saxReader.read("src/test.xml");
//获取根节点
Element root = document.getRootElement();
for(Iterator<Element> it = root.elementIterator();it.hasNext();)
{
Element element = (Element)it.next();
//添加节点
Element sex = element.addElement("sex");
//添加文本
sex.setText("man");
}
//构造函数参数,回写操作
FileOutputStream file = new FileOutputStream("src/test.xml");
OutputFormat format = OutputFormat.createPrettyPrint();//漂亮格式
// OutputFormat format = OutputFormat.createCompactFormat();//紧凑格式
//回写xml
XMLWriter xmlWriter = new XMLWriter(file,format);
xmlWriter.write(document);
xmlWriter.close();
}
//查询xml的name元素的值
public static void selectName() throws Exception
{
//创建解析器
SAXReader saxReader = new SAXReader();
//Document对象
Document document = saxReader.read("src/test.xml");
//根节点
Element root = document.getRootElement();
//得到p节点
List<Element> list = root.elements("p");
//遍历List集合
for(Element element :list)
{
//element是每一个p元素
//得到p下面的name元素
Element name = element.element("name");
//得到name里面text
String text = name.getText();
System.out.println(text);
}
}
//获取p属性id和name的值,里面Dom4jutils是工具类,封装了回写操作和获取document的方法
public static void getValues()throws Exception
{
Document document = Dom4jutils.getDocument(Dom4jutils.PATH);
Element root = document.getRootElement();
Element p = root.element("p");
String id = p.attributeValue("id");
String name = p.attributeValue("name");
System.out.println("id:"+id+" name:"+name);
}
-XPath解析
// XPath解析xml
public static void getNameAll()throws Exception
{
Document document = Dom4jutils.getDocument(Dom4jutils.PATH);
//使用selectNodes方法获取所有的name
List<Node> selectNodes = document.selectNodes("//name");
//遍历集合
for (Node node : selectNodes) {
//node就是每一个name元素
String text = node.getText();
System.out.println(text);
}
}
// 获取第一个name元素
public static void getfirstName()throws Exception
{
Document document = Dom4jutils.getDocument(Dom4jutils.PATH);
Node node =document.selectSingleNode("//name[@name]");
System.out.println("name:"+node.getText());
}
6、student案例,用dom4j实现学生信息管理
</pre>
</body>
</html>