进阶学习之XML

xiaoxiao2021-03-01  47

一、XML语法

0、引入 HTML: 负责网页的结构 CSS: 负责网页的样式(美观) Javascript: 负责在浏览器端与用户进行交互。 XML:软件配置文件(最常见)、作为小型数据库

1、文档声明 在编写XML文档时,需要先使用文档声明,声明XML文档的类型。 ① 最简单的声明语法(version:xml的版本号) <?xml version="1.0" ?> ② 用encoding属性说明文档的字符编码(解码) <?xml version="1.0" encoding="GB2312" ?> ③ 用standalone属性说明文档是否独立 <?xml version="1.0" encoding="GB2312" standalone="yes" ?>

注意:如果在ecplise工具中开发xml文件,保存xml文件时自动按照文档声明的encoding来保存文件;如果用记事本工具修改xml文件,注意保存xml文件按照文档声明的encoding的码表来保存。

2、标签命名规范 ① 一个标签有如下几种书写形式,例如: 包含标签体:<a>www.itcast.cn</a> 不含标签体的:<a></a>简写为:<a/> (空标签) ② xml标签名称区分大小写:例如<P>和<p>是两个不同的标签 ③ xml标签一定要正确配对 ④ xml标签名中间不能使用空格 ⑤ xml标签名不能以数字开头 ⑥ 名称中间不能包含冒号(:) 注意: 在一个xml文档中,有且仅有一个根标签 对于XML标签中出现的所有空格和换行,XML解析程序都会当作标签内容进行处理。例如:下面两段内容的意义是不一样的。由于在XML中,空格和换行都作为原始内容被处理,所以,在编写XML文件时,使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要被迫改变。

3、属性 ① 属性值一定要用双引号(")或单引号(’)引起来(HTML不一定要带引号) ② 定义属性必须遵循与标签相同的命名规范 ③ 在一个xml文档中只能存在一个根标签 ④ 标签属性所代表的信息,也可以被改成用子元素的形式来描述,例如:

<input> <name>text</name> </input>

4、注释 Xml文件中的注释采用<!--注释-->格式。 注意:XML声明之前不能有注释

5、转义字符 在xml中内置了一些特殊字符,这些特殊字符不能直接被浏览器原样输出,如果希望把这些特殊字符按照原样输出到浏览器,对这些特殊字符进行转义

特殊字符转义字符<<>>""&&空格&nsbp;

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

<![CDATA[ <itcast> <br/> </itcast> ]]>

7、处理指令PI(processing instruction) ① 处理指令用来指挥解析引擎如何解析XML文档内容。 例如,在XML文档中可以使用xml-stylesheet指令,通知XML解析引擎,应用css文件显示xml文档内容:<?xml-stylesheet type="text/css" href="1.css"?> ② 处理指令必须以<?作为开头,以?>作为结尾,XML声明语句就是最常见的一种处理指令。 ③ 作用: 告诉xml解析如果解析xml文档

二、XML解析

1、作用:xml文件除了给开发者看,更多的情况使用程序读取xml文件的内容(这叫做xml解析)

2、XML解析方式(原理不同):DOM解析、SAX解析

3、XML解析工具 ① DOM解析: ◆ JAXP (oracle-Sun公司官方) ◆ JDOM工具(非官方) ◆ Dom4J工具(非官方):三大框架(struts、Hibernate、spring)默认读取xml的工具就是 ② SAX解析:Sax解析工具(oracle-sun公司官方)

4、DOM解析原理:xml解析器一次性把整个xml文档加载进内存,然后在内存中构建一棵Document的对象树,通过Document对象得到树上的节点对象,然后通过节点对象访问(操作)到xml文档的内容(标签、属性、文本、注释)。

5、Dom4j工具:非官方,不在jdk中 ① 使用步骤 ◆ 导入dom4j的核心包:dom4j-1.6.1.jar ◆ 编写Dom4j读取xml文件代码

public static void main(String[] args) { try { //1.创建一个xml解析器对象 SAXReader reader = new SAXReader(); //2.读取xml文档,返回Document对象 Document doc = reader.read(new File("./src/contact.xml")); System.out.println(doc); } catch (DocumentException e) { e.printStackTrace(); throw new RuntimeException(e); } }

② Domj4读取xml文件

public class Demo1 { /** * 获取节点信息 */ @Test public void test1() throws Exception{ //1.读取xml文档,返回Document对象 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); //2.nodeIterator: 得到当前节点下的所有子节点对象(不包含孙以下的节点) Iterator<Node> it = doc.nodeIterator(); while(it.hasNext()){//判断是否有下一个元素 Node node = it.next();//取出元素 String name = node.getName();//得到节点名称 //继续取出其下面的子节点 //只有标签节点才有子节点 //判断当前节点是否是标签节点 if(node instanceof Element){ Element elem = (Element)node; Iterator<Node> it2 = elem.nodeIterator(); while(it2.hasNext()){ Node n2 = it2.next(); System.out.println(n2.getName()); } } } } /** * 获取所有节点信息方式:遍历 * @throws Exception */ @Test public void test2() throws Exception{ //1.读取xml文档,返回Document对象 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); //得到根标签 Element rooElem = doc.getRootElement(); getChildNodes(rooElem); } /** * 方法:获取传入的标签下的所有子节点 * @param elem */ private void getChildNodes(Element elem){ System.out.println(elem.getName()); //得到子节点 Iterator<Node> it = elem.nodeIterator(); while(it.hasNext()){ Node node = it.next(); //判断是否是标签节点 if(node instanceof Element){ Element el = (Element)node; //递归 getChildNodes(el); } }; } /** * 获取标签信息 */ @Test public void test3() throws Exception{ //1.读取xml文档,返回Document对象 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); //2.得到根标签 Element rootElem = doc.getRootElement(); //得到标签名称 String name = rootElem.getName(); System.out.println(name); //3.得到当前标签下指定名称的第一个子标签 /* Element contactElem = rootElem.element("contact"); System.out.println(contactElem.getName()); */ //4.得到当前标签下指定名称的所有子标签 /* Iterator<Element> it = rootElem.elementIterator("contact"); while(it.hasNext()){ Element elem = it.next(); System.out.println(elem.getName()); } */ //5.得到当前标签下的的所有子标签 List<Element> list = rootElem.elements(); //遍历List的方法 //1)传统for循环、2)增强for循环、3)迭代器 /*for(int i=0;i<list.size();i++){ Element e = list.get(i); System.out.println(e.getName()); }*/ /*for(Element e:list){ System.out.println(e.getName()); }*/ /* Iterator<Element> it = list.iterator(); //ctrl+2 松开 l while(it.hasNext()){ Element elem = it.next(); System.out.println(elem.getName()); }*/ //获取更深层次的标签(方法只能一层层地获取) Element nameElem = doc.getRootElement(). element("contact").element("name"); System.out.println(nameElem.getName()); } /** * 获取属性信息 */ @Test public void test4() throws Exception{ //1.读取xml文档,返回Document对象 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); //获取属性:(先获的属性所在的标签对象,然后才能获取属性) //1.得到标签对象 Element contactElem = doc.getRootElement().element("contact"); //2.得到属性 //2.1 得到指定名称的属性值 /* String idValue = contactElem.attributeValue("id"); System.out.println(idValue); */ //2.2 得到指定属性名称的属性对象 /*Attribute idAttr = contactElem.attribute("id"); //getName:属性名称、getValue:属性值 System.out.println(idAttr.getName() +"=" + idAttr.getValue());*/ //2.3 得到所有属性对象,返回LIst集合 /*List<Attribute> list = contactElem.attributes(); //遍历属性 for (Attribute attr : list) { System.out.println(attr.getName()+"="+attr.getValue()); }*/ //2.4 得到所有属性对象,返回迭代器 Iterator<Attribute> it = contactElem.attributeIterator(); while(it.hasNext()){ Attribute attr = it.next(); System.out.println(attr.getName()+"="+attr.getValue()); } } /** * 获取文本信息 */ @Test public void test5() throws Exception{ //1.读取xml文档,返回Document对象 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); /** * 注意: 空格和换行也是xml的内容 String content = doc.getRootElement().getText(); System.out.println(content); */ //获取文本(先获取标签,再获取标签上的文本) Element nameELem = doc.getRootElement().element("contact").element("name"); //1. 得到文本 String text = nameELem.getText(); System.out.println(text); //2. 得到指定子标签名的文本内容 String text2 = doc.getRootElement().element("contact").elementText("phone"); System.out.println(text2); } } 获取返回值获取节点[Element对象].nodeIterator();//获取当前标签节点下的所有子节点Iterator获取标签[Document对象].getRootElement();//获取xml文档的根标签Element[ELement对象].element(“标签名”);//指定名称的第一个子标签Element[Element对象].elementIterator(“标签名”);//指定名称的所有子标签Iterator<Element>[Element对象].elements(); //获取所有子标签List<Element>获取属性[Element对象].attributeValue(“属性名”);//获取指定名称的属性值String[Element对象].attribute(“属性名”);//获取指定名称的属性对象Attribute[Attribute对象].getName();//获取属性名称[Attibute对象].getValue();//获取属性值[Element对象].attributes();//获取所有属性对象List<Attribute>[Element对象].attibuteIterator();//获取所有属性对象Iterator<Attribute>获取文本[Element对象].getText();//获取当前标签的文本[Element对象].elementText(“标签名”);//获取当前标签的指定名称的子标签的文本内容 /** * 把xml文档信息封装到对象中 **/ public class Demo2 { public static void main(String[] args) throws Exception{ List<Contact> list = new ArrayList<Contact>(); //读取xml,封装对象 SAXReader reader = new SAXReader(); Document doc = reader.read(new File("./src/contact.xml")); //读取contact标签 Iterator<Element> it = doc.getRootElement().elementIterator("contact"); while(it.hasNext()){ Element elem = it.next(); //创建Contact Contact contact = new Contact(); contact.setId(elem.attributeValue("id")); contact.setName(elem.elementText("name")); contact.setAge(elem.elementText("age")); contact.setPhone(elem.elementText("phone")); contact.setEmail(elem.elementText("email")); contact.setQq(elem.elementText("qq")); list.add(contact); } for (Contact contact : list) { System.out.println(contact); } } } public class Contact { private String id; private String name; private String age; private String phone; private String email; private String qq; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getQq() { return qq; } public void setQq(String qq) { this.qq = qq; } @Override public String toString() { return "Contact [age=" + age + ", email=" + email + ", id=" + id + ", name=" + name + ", phone=" + phone + ", qq=" + qq + "]"; } }

③ Domj4修改xml文件

//写出内容到xml文档 public class Demo3 { public static void main(String[] args) throws Exception{ //一、读取或创建一个Document对象 //读取xm文件 Document doc = new SAXReader().read(new File("./src/contact.xml")); /** * 1.指定写出的格式 */ OutputFormat format = OutputFormat.createCompactFormat(); //紧凑的格式:去除空格换行.项目上线的时候 //OutputFormat format = OutputFormat.createPrettyPrint(); //漂亮的格式:有空格和换行.开发调试的时候 /** * 2.指定生成的xml文档的编码 * 同时影响了xml文档保存时的编码和xml文档声明的encoding的编码(xml解析时的编码) * 结论: 使用该方法生成的xml文档避免中文乱码问题。 */ format.setEncoding("utf-8"); //二、修改Document对象内容 //三、把修改后的Document对象写出到xml文档中 //指定文件输出的位置 FileOutputStream out = new FileOutputStream("e:/contact.xml"); //1.创建写出对象 //XMLWriter writer = new XMLWriter(out); XMLWriter writer = new XMLWriter(out,format); //2.写出对象 writer.write(doc); //3.关闭流 writer.close(); } } 功能解释增加DocumentHelper.createDocument()增加文档addElement(“名称”)增加标签addAttribute(“名称”,“值”)增加属性修改Attribute.setValue(“值”)修改属性值Element.addAtribute(“同名的属性名”,“值”)修改同名的属性值Element.setText(“内容”)修改文本内容删除Element.detach()删除标签Attribute.detach()删除属性 public class Demo4 { /** * 增加:文档、标签、属性 */ @Test public void test1() throws Exception{ /** * 1.创建文档 */ Document doc = DocumentHelper.createDocument(); /** * 2.增加标签 */ Element rootElem = doc.addElement("contactList"); //doc.addElement("contactList"); Element contactElem = rootElem.addElement("contact"); contactElem.addElement("name"); /** * 3.增加属性 */ contactElem.addAttribute("id", "001"); contactElem.addAttribute("name", "eric"); //把修改后的Document对象写出到xml文档中 FileOutputStream out = new FileOutputStream("e:/contact.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); } /** * 修改:属性值,文本 * @throws Exception */ @Test public void test2() throws Exception{ Document doc = new SAXReader().read(new File("./src/contact.xml")); /** * 方案一:修改属性值 1.得到标签对象 2.得到属性对象 3.修改属性值 */ //1.1 得到标签对象 Element contactElem = doc.getRootElement().element("contact"); //1.2 得到属性对象 Attribute idAttr = contactElem.attribute("id"); //1.3 修改属性值 idAttr.setValue("003"); /** * 方案二:修改属性值 1.得到标签对象 2.通过增加同名属性的方法,修改属性值 */ //1.1 得到标签对象 Element contactElem = doc.getRootElement().element("contact"); //1.2 通过增加同名属性的方法,修改属性值 contactElem.addAttribute("id", "004"); /** * 修改文本:1.得到标签对象 2.修改文本 */ Element nameElem = doc.getRootElement().element("contact").element("name"); nameElem.setText("李四"); FileOutputStream out = new FileOutputStream("e:/contact.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); } /** * 删除:标签,属性 * @throws Exception */ @Test public void test3() throws Exception{ Document doc = new SAXReader().read(new File("./src/contact.xml")); /** * 1.删除标签:1.1 得到标签对象 1.2 删除标签对象 */ //1.1 得到标签对象 Element ageElem = doc.getRootElement().element("contact").element("age"); //1.2 删除标签对象 ageElem.detach(); //ageElem.getParent().remove(ageElem); /** * 2.删除属性:2.1得到属性对象 2.2 删除属性 //2.1 得到属性对象 //得到第二个contact标签 Element contactElem = (Element)doc.getRootElement().elements().get(1); //2.2 得到属性对象 Attribute idAttr = contactElem.attribute("id"); //2.3 删除属性 idAttr.detach(); //idAttr.getParent().remove(idAttr); FileOutputStream out = new FileOutputStream("e:/contact.xml"); OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out,format); writer.write(doc); writer.close(); } }

6、XPath技术 ① 问题:当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦 ② XPath作用:主要是用于快速获取所需的节点对象。 ③ 在dom4j中如何使用XPath技术 ◆ 导入XPath支持jar包: jaxen-1.1-beta-6.jar ◆ 使用XPath方法

List<Node> selectNodes("xpath表达式"); 查询多个节点对象 Node selectSingleNode("xpath表达式"); 查询一个节点对象

④ XPath语法

功能名称解释/绝对路径表示从xml的根位置开始或子元素(一个层次结构)//相对路径表示不分任何层次结构的选择元素*通配符表示匹配所有元素[]条件表示选择什么条件下的元素@属性表示选择属性节点and关系表示条件的与关系(等价于&&)text()文本表示选择文本内容 public class Demo4 { public static void main(String[] args) throws Exception { Document doc = new SAXReader().read(new File("./src/contact.xml")); String xpath = ""; /** * 1. / 绝对路径:表示从xml的根位置开始或子元素(一个层次结构) */ xpath = "/contactList"; xpath = "/contactList/contact"; /** * 2. // 相对路径:表示不分任何层次结构的选择元素。 */ xpath = "//contact/name"; xpath = "//name"; /** * 3. * 通配符:表示匹配所有元素 */ xpath = "/contactList/*"; //根标签contactList下的所有子标签 xpath = "/contactList//*";//根标签contactList下的所有标签(不分层次结构) /** * 4. [] 条件:表示选择什么条件下的元素 */ //带有id属性的contact标签 xpath = "//contact[@id]"; //第二个的contact标签 xpath = "//contact[2]"; //选择最后一个contact标签 xpath = "//contact[last()]"; /** * 5. @ 属性:表示选择属性节点 */ xpath = "//@id"; //选择id属性节点对象,返回的是Attribute对象 xpath = "//contact[not(@id)]";//选择不包含id属性的contact标签节点 xpath = "//contact[@id='002']";//选择id属性值为002的contact标签 xpath = "//contact[@id='001' and @name='eric']";//选择id属性值为001,且name属性为eric的contact标签 /** *6. text():表示选择文本内容 */ //选择name标签下的文本内容,返回Text对象 xpath = "//name/text()"; xpath = "//contact/name[text()='张三']";//选择姓名为张三的name标签 List<Node> list = doc.selectNodes(xpath); for (Node node : list) { System.out.println(node); } } }

7、SAX解析 ① DOM解析原理:一次性把xml文档加载进内存,然后在内存中构建Document树,对内存要求比较高。 缺点: 不适合读取大容量的xml文件,容易导致内存溢出。 SAX解析原理: 加载一点,读取一点,处理一点,对内存要求比较低。 ② SAX解析工具:Sun公司提供的内置在jdk中:org.xml.sax.*; ③ 核心的API(SAXParser类) 用于读取和解析xml文件对象 ◆parse(File f, DefaultHandler dh)方法: 解析xml文件 【File:表示要读取的xml文件;DefaultHandler:SAX事件处理程序,要使用DefaultHandler的子类】

public class Demo5 { public static void main(String[] args) throws Exception{ //1.创建SAXParser对象 SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); //2.调用parse方法读取xml文件 /** * 参数一: xml文档 * 参数二: DefaultHandler的子类[一个类继承class 类名(extends DefaultHandler)在调用是创建传进去 */ parser.parse(new File("./src/contact.xml"), new MyDefaultHandler()); //输出文档 String content = handler.getContent(); System.out.println(content); } } } /** * SAX处理程序(如何解析xml文档) * @author APPle * */ public class MyDefaultHandler extends DefaultHandler { private StringBuffer sb = new StringBuffer(); //获取xml信息 public String getContent(){ return sb.toString(); } /** * 开始文档时调用 */ @Override public void startDocument() throws SAXException { System.out.println("MyDefaultHandler.startDocument()"); } /** * 开始标签时调用 * @param qName: 表示开始标签的标签名 * @param attributes: 表示开始标签内包含的属性列表 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { sb.append("<"+qName); //判断是否有属性 if(attributes!=null){ for(int i=0;i<attributes.getLength();i++){ //得到属性名称 String attrName = attributes.getQName(i); //得到属性值 String attrValue = attributes.getValue(i); sb.append(" "+attrName+"=\""+attrValue+"\""); } } sb.append(">"); } /** * 结束标签时调用 * @param qName: 结束标签的标签名称 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { sb.append("</"+qName+">"); } /** * 读到文本内容的时调用 * @param ch: 表示当前读完的所有文本内容 * @param start: 表示当前文本内容的开始位置 * @param length: 表示当前文本内容的长度 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { //得到当前读取的文本 String content = new String(ch,start,length); sb.append(content); } /** * 结束文档时调用 */ @Override public void endDocument() throws SAXException { System.out.println("MyDefaultHandler.endDocument()"); } }

◆ DefaultHandler类的API

void startDocument():在读到文档开始时调用 void endDocument():在读到文档结束时调用 void startElement(String uri, String localName, String qName, Attributes attributes):读到开始标签时调用 void endElement(String uri, String localName, String qName):读到结束标签时调用 void characters(char[] ch, int start, int length):读到文本内容时调用 public class Demo3 { public static void main(String[] args)throws Exception { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); MyDefaultHandler3 handler = new MyDefaultHandler3(); parser.parse(new File("./src/contact.xml"), handler); List<Contact> list = handler.getList(); for (Contact contact : list) { System.out.println(contact); } } } public class MyDefaultHandler3 extends DefaultHandler { //存储所有联系人对象 private List<Contact> list = new ArrayList<Contact>(); public List<Contact> getList(){ return list; } //保存一个联系人信息 private Contact contact; /** * 思路: * 1)创建Contact对象 * 2)把每个contact标签内容存入到Contact对象 * 3)把Contact对象放入List中 */ //用于临时存储当前读到的标签名 private String curTag; @Override public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException { curTag = qName; //读取到contact的开始标签创建Contact对象 if("contact".equals(qName)){ contact = new Contact(); //设置id值 contact.setId(attributes.getValue("id")); } } @Override public void characters(char[] ch, int start, int length)throws SAXException { //当前文本内容 String content = new String(ch,start,length); if("name".equals(curTag)){ contact.setName(content); } if("age".equals(curTag)){ contact.setAge(content); } if("phone".equals(curTag)){ contact.setPhone(content); } if("email".equals(curTag)){ contact.setEmail(content); } if("qq".equals(curTag)){ contact.setQq(content); } } @Override public void endElement(String uri, String localName, String qName)throws SAXException { //设置空时为了避免空格换行设置到对象的属性中 curTag = null; //读到contact的结束标签放入List中 if("contact".equals(qName)){ list.add(contact); } } }

8、DOM解析与SAX解析区别 ① DOM解析原理:一次性加载xml文档,不适合大容量的文件读取;DOM解析可以任意进行增删改查;DOM解析任意读取任何位置的数据,甚至往回读;DOM解析面向对象的编程方法(Node,Element,Attribute)Java开发者编码比较简单。 ② SAX解析原理:加载一点,读取一点,处理一点,适合大容量文件的读取;SAX解析只能读取;SAX解析只能从上往下,按顺序读取,不能往回读;SAX解析基于事件的编程方法,java开发编码相对复杂。

三、XML约束

1、XML语法: 规范xml文件的基本编写规则(由w3c组织制定的) XML约束: 规范xml文件数据内容格式的编写规则(由开发者自行定义)

2、XML约束技术 ① DTD约束:语法相对简单,功能也相对简单,学习成本也低。 ② Schema约束:语法相对复杂,功能也相对强大,学习成本相对高

3、DTD约束 ① 导入DTD方式 ◆ 内部导入

<!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]>

◆ 外部导入 ◇ 本地文件系统的外部导入:<!DOCTYPE 根元素 SYSTEM "文件名.dtd"> ◇ 公共的外部导入:<!DOCTYPE 根元素 PUBLIC "http://gz.itcast.cn/itcast.dtd"> ② DTD语法 ◆ 约束标签:<!ELEMENT 元素名称 类别> 或 <!ELEMENT 元素名称 (元素内容)> ◇ 类别: 空标签: EMPTY,表示元素一定是空元素 普通字符串:(#PCDATA),表示元素的内容一定是普通字符串(不能含有子标签) 任何内容: ANY,表示元素的内容可以是任意内容(包括子标签) ◇ 元素内容: 顺序问题:<!ELEMENT 元素名称 (子元素名称1,子元素名称2,.....)> 次数问题: 标签:必须且只出现1次; 标签+:至少出现1次; 标签*: 0或n次; 标签?: 0 或1次。

◆ 约束属性<!ATTLIST 元素名称 属性名称 属性类型 默认值> ◇ 默认值: #REQUIRED:属性值是必需的 #IMPLIED :属性不是必需的 #FIXED value:属性不是必须的,但属性值是固定的值value ◇ 属性类型: CDATA:表示普通字符串 (en1|en2|..):表示一定是任选其中的一个值 ID:表示在一个xml文档中该属性值必须唯一,值不能以数字开头

4、Schema约束 Schema也是一种用于定义和描述 XML 文档结构与内容的模式语言,其出现是为了克服 DTD 的局限性。 ① Schema约束特点: ◆ XML Schema符合XML语法结构。 ◆ DOM、SAX等XML API很容易解析出XML Schema文档中的内容。 ◆ XML Schema对名称空间支持得非常好。 ◆ XML Schema比XML DTD支持更多的数据类型,并支持用户自定义新的数据类型。 ◆ XML Schema定义约束的能力非常强大,可以对XML实例文档作出细致的语义限制。 ◆ XML Schema不能像DTD一样定义实体,比DTD更复杂,但Xml Schema现在已是w3c组织的标准,它正逐步取代DTD。 ② 名称空间:告诉xml文档的哪个元素被哪个schema文档约束,在一个xml文档中不同的标签可以受到不同的schema文档的约束 ◆ 一个名称空间受到schema文档约束的情况

//book.xsd文件 <?xml version="1.0" encoding="UTF-8" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.itcast.cn" elementFormDefault="qualified"> <xs:element name='书架' > <xs:complexType> <xs:sequence maxOccurs='unbounded' > <xs:element name='书' > <xs:complexType> <xs:sequence> <xs:element name='书名' type='xs:string' /> <xs:element name='作者' type='xs:string' /> <xs:element name='售价' type='xs:string' /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> <?xml version="1.0" encoding="UTF-8"?> <itcast:书架 xmlns:itcast="http://www.itcast.cn[解释:名称空间别名]" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance[解释:公开的名称空间]" xsi:schemaLocation="http://www.itcast.cn[解释:名称空间别名] book.xsd[解释:schema文件地址]"> <itcast:书> <itcast:书名>JavaScript网页开发</itcast:书名> <itcast:作者>张孝祥</itcast:作者> <itcast:售价>28.00元</itcast:售价> </itcast:书> </itcast:书架> [解释:xml文档定义了一个itcast名称的名称空间,别名是http://www.itcast.cn。书签标签引用了ITcast名称的名称空间。http://www.itcast.cn的schema文件地址在当前目录下的book.xsd中]

◆ 名称空间受到多个schema文档约束的情况

<书架 xmlns="http://www.it315.org/xmlbook/schema" xmlns:demo="http://www.it315.org/demo/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.it315.org/xmlbook/schema http://www.it315.org/xmlbook.xsd http://www.it315.org/demo/schema http://www.it315.org/demo.xsd"> <书> <书名>JavaScript网页开发</书名> <作者>张孝祥</作者> <售价 demo:币种=”人民币”>28.00元</售价> </书> </书架>

◆ 默认名称空间的情况

<书架 xmlns="http://www.it315.org/xmlbook/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=“http://www.it315.org/xmlbook/schema book.xsd"> <书> <书名>JavaScript网页开发</书名> <作者>张孝祥</作者> <售价>28.00元</售价> </书> </书架>

◆ 不使用名称空间

<书架 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xmlbook.xsd"> <书> <书名>JavaScript网页开发</书名> <作者>张孝祥</作者> <售价>28.00元</售价> </书> </书架>
转载请注明原文地址: https://www.6miu.com/read-3650334.html

最新回复(0)