- xml是可扩展标记语言
- html是用来显示数据的,而xml是用来存储数据的。
- 实体引用与CDATA区:<;代表的是<号,>;代表大于号>。:与转意字符的用法一致。
- xml文件的解析分为三种:DOM、SAX、PULL,DOM解析需要一次性加载完所有的内容,占用内存较大。所以一般使用较少
- SAX工作原理:
- 读到最上层标签则初始化list集合
- 读到标签就开始读取其中的等子元素。
- 把student子元素中的值存入一个student对象中,然后添加到集合list中。
- 逐个取出。
- SAX解析代码:具体事物是交由handle事件处理对象去执行的。(以students.xml文件为例)
//创建解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//创建解析对象
SAXParser parser = factory.newSAXParser();
//创建事件处理对象
HandlerForStudent handle = new HandlerForStudent();
URL url = new URL("http://localhost:8080/TestTomcat/students.xml" );
InputStream is = url.openStream();
//handle对象不用去调用方法,在这里它会自动执行复写父类的所有方法。是一种回调的用法。
parser.parse( is, handle);
List list = handle.getList();
for (Student student : list) {
System. out.println( student);
}
- Handle类处理部分:分为四个方法,执行顺序如下1,2,3,4。除了1其他都是循环执行的。
1.startDocument():文件开始函数,对list集合进行初始化
public void startDocument() throws SAXException {
list = new ArrayList();
}
2.startElement (String uri, String localName, String qName , Attributes attributes ):开始标签执行函数,qName为标签的名称,attributes为对象属性。
public void startElement(String uri, String localName, String qName , Attributes attributes ) throws SAXException {
if ( qName.equals( "student")) {
//如果标签名为student则初始化对象。
for ( int i = 0; i < attributes.getLength(); i++) {
//attributes.getLength()返回的是对象属性的个数。这份xml文档中只是在标签中添加了代表学生对象的id属性。
//attributes 是属性
if (attributes.getQName(i ).equals("id" )) {
student.setId( attributes.getValue( i));
}
}
}
//把标签值赋给全局变量tag,使characters方法中可判断标签,读出不同标签的数据。
tag = qName;
}
3.
endElement(String uri, String localName, String qName):结束标签
public void endElement(String uri, String localName, String qName) throws SAXException {
//如果此结束标签为student则说明一个对象已经读完,把封装好的对象加入到list集合中。
if (qName.equals( "student")) {
list.add( student);
}
}
4.
characters( char[] ch, int start, int length):把读到的内容存放在字符数组中(包含了很多空格)
public void characters(char[] ch, int start, int length) throws SAXException {
//把字符数组转换为一个字符串
String info = new String(ch,start,length);
//info.trim()方法是把字符串中空格全部清空,之后判断如果不为空则进行标签判断
if (! "".equals(info.trim())) {
if ( tag.equals( "name")) {
student.setName(info);
}
if ( tag.equals( "age")) {
student.setAge(Integer. parseInt(info));
}
if ( tag.equals( "phonenum")) {
student.setPhonenum(info);
}
}
}
- Student类只需要定义好xml文件标签中的子元素所对应的变量,然后封装好,复写toString()方法方便打印。
- PULL解析:
- 通过Pull的方式来解析XMl文件。原理与SAX解析方式大致相同,与SAX方式对比有一个比较大的优点就是过程可控性强,通过switch()语句在主程序中能方便控制解析过程。而SAX方式则把对xml的解析过程全部交由handler对象来做,因此可控性差了。
- Pull解析代码:
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();//创建pull解析工厂
XmlPullParser parser = factory.newPullParser(); //创建pull解析对象
parser.setInput( new FileReader( "students.xml"));//设置文件输入对象
//获取状态值:event它的值分为:END_DOCUMENT、START_DOCUMENT、START_TAG、END_TAG几种。与SAX解析中的四个方法相似,此处是通过循环判断event的值来做出相对应的操作。
int event = parser.getEventType();
List list = null;
Student student = null;
while(event != XmlPullParser. END_DOCUMENT){//如果状态值为pull解析器的指定文档结束常量值则停止读取文件
switch (event) {
case XmlPullParser. START_DOCUMENT:
list = new ArrayList();
break;
case XmlPullParser. START_TAG:
if( "student".equals(parser.getName())){
student = new Student();
int len = parser.getAttributeCount();//属性数量
for ( int i = 0; i < len; i++) {
student.setId(parser.getAttributeValue(i));
}
}
if ( "name".equals(parser.getName())) {
student.setName(parser.nextText()); //注意这里是nextText而不是getText
}
if ( "age".equals(parser.getName())) {
student.setAge(Integer. parseInt(parser.nextText()));
}
if ( "phonenum".equals(parser.getName())) {
student.setPhonenum(parser.nextText());
}
break;
case XmlPullParser. END_TAG:
if ( "student".equals(parser.getName())) {
list.add(student);
}
break;
default:
break;
}
event = parser.next(); //读完一个标签再往下读,然后再去做判断是否读到结束标志。
}