导图社区 XML编程可扩展标记语言知识点笔记
XML编程可扩展标记语言知识点笔记,包括它的书写要求、组成、实体引用(类似java的转义字符)、命名规则、pull解析等等。
编辑于2022-11-02 10:43:51 广东XML编程可扩展标记语言知识点笔记
什么是XML
eXtended Markup Language可扩展标记语言
为什么要有XML
XML是一种数据存储和传输的常用格式
书写要求
1.开始标签和结束标签对应。
2.必须正确地嵌套,重复标签不能嵌套
3.区分大小写
4.文档必须有根元素
区别于对象根元素
5.它的属性值须加引号
6.注释
组成
前导区
version:版本号;encoding:字符集
数据区
XML 文档形成一种树结构
XML 文档必须包含根元素。该元素是所有其他元素的父元素
XML 文档中的元素形成了一棵文档树。这棵树从根部开始,并扩展到树的最底端
实体引用(类似java的转义字符)
< < 小于
less than
> > 大于
greater than
& & 与
ampersand['æmpəsænd]
' ' 单引号
apostrophe [ə'pɔstrəfi] 撇号
" " 引号
quote
命名规则
名称可以含字母、数字以及其他的字符
名称不能以数字或者标点符号开始
名称不能以字符 “xml”(或者 XML、Xml)开始
名称不能包含空格
可使用任何名称,没有保留的字词
SAX解析:Simple APIs for XML XML简单应用程序接口 在javax.xml.parsers包中
以事件驱动的方式解析, 即找开始结束标签的方式
原理:
SAX的工作原理简单地说就是对文档进行顺序扫描,当扫描到 文档(document)开始与结束、元素(element)开始与结束、 等地方时通知事件处理函数,由事件处理函数做相应动作, 然后继续同样的扫描,直至文档结束。
SAX解析是JDK自带的解析方式(android中也可以直接使用),包括一组接口和类
案例1:解析student.xml, 把解析出来的Student对象装入List, 元素没有属性,有子元素; day29_xml.sax
1.创建sax解析器的工厂
javax.xml.parsers.SAXParserFactory
SAXParserFactory factory = SAXParserFactory.newInstance();
2.创建sax解析器
javax.xml.parsers.SAXParser
SAXParser parser = factory.newSAXParser();
3.自定义MyHandler继承 DefaultHandler类
org.xml.sax.helpers.DefaultHandler
重写方法
startDocument():xml文档解析的开始
初始化list
endDocument():xml文档解析的结束
无特定任务
startElement(String uri, String localName, String qName, Attributes attributes):节点解析的开始. qName参数有用,表示当前正在解析的标签名. 如果标签中有属性,则attributes参数有用. 任务:tag=qName,如果是对象根元素,则初始化对象
endElement(String uri, String localName, String qName): 节点解析的结束.qName参数有用. 任务:设置tag="",如果是对象根元素,加入list
characters(char[] ch, int start, int length): 文本节点的解析.设置对象属性.所有参数都有用
String content = new String(ch,start,length); if("name".equals(tag)){ student.setName(content); }...
新增方法与属性
Student student;
保存当前对象
String tag;
记录当前解析到的标签
List<Student> list;//保存已经解析完毕的Student对象, 在startDocument()方法中初始化
public List<Student> getList()
在场景类中调用, 用于获取解析结果
4.解析xml文档
MyHandler handler = new MyHandler(); 自定义的DefaultHandler的子类,用来制定解析的逻辑和方式
parser.parse(new File("student.xml"), handler); xml文件放在项目的根目录下
5.用handler对象调用方法获取解析结果
List<Student> list = handler.getList();
for(Student s : list){System.out.println(s);}
练习1:cat; day29_xml.sax 不带属性的非单行对象cat.xml
案例2:把Student对象装入List, 元素有属性:<student id="1">... student02.xml day29_xml.sax.SAXTest03
自定义MyHandler extends DefaultHandler
新增方法与属性
Student student;
List<Student> list;在startDocument()方法中初始化
List<Student> getList()
String tag;
在startElement(String uri, String localName, String qName, Attributes attributes) 方法中获取属性的值
if(attributes!=null){ int length = attributes.getLength();//出现了多少个属性 for(int i=0;i String name = attributes.getQName(i); String value = attributes.getValue(i); if("id".equals(name)){ student.setId(Integer.parseInt(value)); } } }
List<Student> list = handler.getList();
解析xml文档
MyHandler handler = new MyHandler();
parser.parse(new File("student02.xml"), handler);
for(Student s : list)System.out.println(s);
练习2:books.xml在多个元素里面有属性
提示:在startElement中分别对qName为title和book的标签 进行属性解析day29...xml04
作业1:用HttpURLConnection下载 并解析web服务器上的student.xml文件
day30.homework01
parser.parse(InputStream,DefaultHandler) 可以不用下载到本地文件再读取文件,直接读取输入流....
xml文件放在WebContent目录下
http://localhost:8080/projectname/student.xml
作业2:用HttpClient下载 并解析web服务器上的student.xml文件
day30.homework02
parser.parse(InputStream,DefaultHandler)
pull解析
pull解析器简介
1.pull解析器是android内置的解析器,解析原理与sax类似
2.pull提供了类似的事件。 如:开始元素和结束元素事件, 使用parser.next()可以进入下一个元素并触发相应的事件,事件将作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法获取下一个Text类型节点的值
kxml2-2.2.2.jar
以事件驱动的方式解析
0:(XmlPullParser.START_DOCUMENT);文档开始
1:(XmlPullParser.END_DOCUMENT);文档结束
2:(XmlPullParser.START_TAG);标签开始
3:(XmlPullParser.END_TAG);标签结束
4:(XmlPullParser.TEXT);
用于处理文本节点
凡是文本,包括空格/换行/元素中的文本(非属性)都会取出来
如果在case 2标签开始 里面进行parser.nextText()调用, 则此处用getText()无法再次取出
步骤
创建pull解析的工厂类对象
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();//注意大小写
创建解析器
XmlPullParser parser = factory.newPullParser();
指定解析文件
parser.setInput(new FileReader("student.xml")); 在项目根目录下,形参是Reader类型.
parser.setInput(new FileInputStream("student.xml"),"utf-8"); 用于解析中文,形参是InputStream类型.
获得事件状态码
int eventType = parser.getEventType();在开始解析之前要先获取一次
循环解析,直到文档结束;
parser.getName();获取标签名称 parser.nextText()获取子标签内部的文本(当tag匹配子元素,而非对象根标签时) parser.getText();XmlPullParser.TEXT中会用到,获取当前节点的文本(适用于单行对象,没有子节点的文档) eventType=parser.next();获取下一个标签的事件类型,用在循环体里面的最后一句
无属性的pull01 student.xml
while (eventType != XmlPullParser.END_DOCUMENT) {//注意别写成if!!! //获得标签名 String tag = parser.getName(); switch (eventType) { case 0://文档开始解析 list = new ArrayList(); break; case 2://标签开始,创建学生对象,并封装属性 if("student".equals(tag)){ student = new Student(); }else if("id".equals(tag)){ student.setId(Integer.parseInt(parser.nextText())); }else if("name".equals(tag)){ student.setName(parser.nextText()); }else if("age".equals(tag)){ student.setAge(Integer.parseInt(parser.nextText())); }else if("sex".equals(tag)){ student.setSex(parser.nextText()); } break; case 3://标签结束,将学生对象存储到集合中 if("student".equals(tag)) list.add(student); break; } eventType = parser.next();//千万别忘了在循环的最后一句写上,否则会死循环 }
练习cat.xml
有属性的pull02(case 2:部分截取) student02.xml
case 2:// 标签开始,创建学生对象,并封装属性 if ("student".equals(tag)) { student = new Student(); int count = parser.getAttributeCount();//获得属性总数量 相当于SAX解析的attributes.getLength() for (int i = 0; i String name = parser.getAttributeName(i);//注意 相当于SAX解析中的attributes.getQName(i) String value = parser.getAttributeValue(i);//注意 相当于SAX解析中的attributes.getValue(i) if("id".equals(name)){ student.setId(Integer.parseInt(value)); } } } else if ("name".equals(tag)) { student.setName(parser.nextText()); } else if ("age".equals(tag)) { student.setAge(Integer.parseInt(parser.nextText())); } else if ("sex".equals(tag)) { student.setSex(parser.nextText()); } break;
练习cat02.xml
xml单行元素的pull解析, 即对象根元素里面没有子元素, 有文本节点month.xml
while (eventType != XmlPullParser.END_DOCUMENT) { String tagName = parser.getName(); switch (eventType) { case XmlPullParser.START_DOCUMENT: list = new ArrayList(); break; case XmlPullParser.START_TAG: if ("month".equals(tagName)) { month = new Month(); int attributeCount = parser.getAttributeCount(); for (int i = 0; i String attrName = parser.getAttributeName(i); String attrValue = parser.getAttributeValue(i); if ("id".equals(attrName)) { month.setId(Integer.parseInt(attrValue)); } else if ("shop".equals(attrName)) { month.setShop(attrValue); } else if ("price".equals(attrName)) { month.setPrice(Double.parseDouble(attrValue)); } } } break; //获取xxx中的有效文本,过滤换行,空格等 case XmlPullParser.TEXT://处理对象根元素里面直接包含的文本节点 String content = parser.getText();//不能用nextText() String core = content.trim();//去掉字符串首尾的空白,只保留核心内容 if (core.length() != 0) { month.setMonthValue(Integer.parseInt(core)); } break; case XmlPullParser.END_TAG: if ("month".equals(tagName)) { list.add(month); } break; } eventType = parser.next();//如果没有,将陷入死循环 }
pull与sax的不同之处
1.pull读取xml文件后触发相应的事件调用方法 返回的是数字。
parser.getEventType()在开始解析之前获取第一个事件类型
parser.next()每次循环的末尾
2.pull可以在程序中控制, 想解析到哪里就可以停止到哪里. 结合break label;
3.Android中更推荐使用pull解析
作业1.解析month.xml文件, 分别使用(SAX和PULL)两种方式
pull
SAX
public void characters(char[] ch, int start, int length) throws SAXException { String content = new String(ch,start,length); // 3 //换行,空格,tab都会作为文本节点获取出来,需要忽略 String core = content.trim();//核心文本 if(core.length()!=0){//只有一个有效的纯文本节点,需要忽略前后的空白 month.setValue(core); } }
作业2.解析student03.xml文件, 分别使用(SAX和PULL)两种方式