Java入门(三) 读取XML文件
2017/6/15
by
CHENJING DING
CHAPTER1 – XML文件
一个简单的XML文档组成
<?xml version="1.0"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
文档的第一行:
包含XML申明,它定义了XML文档的版本号,在这个例子中表示文档将使用XML1.0的规范.
<?xml version="1.0"?>
根元素
下一行定义了文档里面的第一个元素(element)也叫根元素
<note>
子元素
再下面定义了根元素的四个子元素(分别是to, from, heading,和body):
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
根元素的结束标志
最后一行定义了根元素的结束标志。
1. </note>
XML文件仅仅是纯文本
XML不会做任何事情。XML 被设计用来结构化、存储以及传输信息
XML文档形成一种树结构
XML文档必须包含根元素。该元素是所有其他元素的父元素。所有元素均可拥有子元素:
<root>
<child>
<subchild>.....</subchild>
</child>
</root>
父、子以及同胞等术语用于描述元素之间的关系。父元素拥有子元素。相同层级上的子元素成为同胞(兄弟或姐妹)。所有元素均可拥有文本内容和属性。
实体引用
在XML中,一些字符拥有特殊的意义,比如把小于号“<”放在XML元素中,会发生错误,这是因为解析器会把它当作新元素的开始。
<message>if salary < 1000 then</message> <!--是错误的-->
<message>if salary <
1000 then</message> <!--是正确的-->
5个预定义的实体引用
XML文件语法规则
1. 所有的XML元素都必须要有一个结束标志, XML声明没有关闭标签,它不是 XML元素,也不需要关闭标签。
2. XML标志是大小写敏感的,例如标志<Letter>是不同与标志<letter>的.
3. 所有一个标志的开始和结束必须使用同样的大小写
<Message>This is incorrect</message> <!--是错误的-->
<message>This is correct</message> <!--是正确的-->
4. XML的属性值须加引号
5. 在XML文件中,空格会被保留;
XML元素
Xml元素是指从(且包括)开始标签直到(且包括)结束标签的部分。
元素可包含其他元素节点,文本节点,或者属性节点。(关于节点可看下节)
属性
Xml元素可以在开始标签中包含属性。必须加引号,单引号双引号均可使用。
属性和元素比较
下面的三个 XML 文档包含完全相同的信息:
第一个例子中使用了 date 属性:
<note date="08/08/2008">
<to>George</to> <!--这整行是一个元素节点,包含文本节点,内容是George-->
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
第二个例子中使用了 date 元素:
<note>
<date>08/08/2008</date>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
第三个例子中使用了扩展的date 元素(推荐):
<note>
<date>
<day>08</day>
<month>08</month>
<year>2008</year>
</date>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
针对元数据的 XML 属性
有时候会向元素分配 ID 属性。这些 ID 索引可用于标识XML 元素;
<messages>
<note id="501">
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
<note id="502">
<to>John</to>
<from>George</from>
<heading>Re: Reminder</heading>
<body>I will not</body>
</note>
</messages>
元数据(有关数据的数据)应当存储为属性,而数据本身应当存储为元素。
CHAPTER2 – java 解析XML文件
一 用dom4j解析java文件
节点与接口
XML 文档中的每个成分都是一个节点。
1. 整个文档是一个文档节点 即Document节点。在java中Document接口是继承于Node接口,表示整个XML 文档
2. 每个 XML 标签是一个元素节点 即ELEMENT节点。在Java中Element接口继承于Node接口 表示XML 文档中的一个元素
3. 包含在 XML 元素中的文本是文本节点 即Text节点。在java中Text接口继承于CharacterData接口,而CharacterData继承于Node接口,表示 Element 或 Attr 的文本内容
4. 每一个 XML 属性是一个属性节点 即Attr节点。在java中Attr接口继承与Node接口。
5. 注释属于注释节点 即Comment节点。在java中Comment接口继承于CharacterData接口,而CharacterData继承于Node接口
步骤
程序实例
创建File,获取根结点
public void testGetRoot() throws Exception{
SAXReader sax=new SAXReader();//创建一个SAXReader对象
File xmlFile=new File("d:\\test.xml");//根据指定的路径创建file对象
Document document=sax.read(xmlFile);//获取document对象,如果文档无节点,则会抛出Exception提前结束
Element root=document.getRootElement();//获取根节点
this.getNodes(root);//从根节点开始遍历所有节点
}
从指定节点开始,递归遍历所有节点和属性
public void getNodes(Element node){
System.out.println("--------------------");
//当前节点的名称、文本内容和属性
System.out.println("当前节点名称:"+node.getName());//当前节点名称
System.out.println("当前节点的内容:"+node.getTextTrim());//当前节点名称
List<Attribute> listAttr=node.attributes();//当前节点的所有属性的list
for(Attribute attr:listAttr){//遍历当前节点的所有属性
String name=attr.getName();//属性名称
String value=attr.getValue();//属性的值
System.out.println("属性名称:"+name+"属性值:"+value);
}
//递归遍历当前节点所有的子节点
List<Element> listElement=node.elements();//所有一级子节点的list
for(Element e:listElement){//遍历所有一级子节点
this.getNodes(e);//递归
}
}
或者使用迭代器遍历所有节点和属性
以下程序是针对OSMdata获取节点的lon,lat转换成Miller坐标系下的xy,并写入到txt中
package comReadOsm;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* computer xy in MillerCoordinate from latitude and longitude in OSM data,
* then output to a txt file
* @author chenjing ding
*
*/
public class ReadXML {
public static void main(String[] args) throws IOException,
DocumentException {
// define object to write to the file
File pointFile = new File("E:\\Point.txt");
FileOutputStream fosPoint = new FileOutputStream(pointFile);
OutputStreamWriter oswPoint = new OutputStreamWriter(fosPoint);
BufferedWriter bwPoint = new BufferedWriter(oswPoint);
SAXReader reader = new SAXReader();
// the address of original map data
String path = "E:\\aachenboden.osm";
Document document = reader.read(new File(path));
// get root element
Element root = document.getRootElement();
// traverse all child node of osm
double latValue = 0.0;
double lonValue = 0.0;
double[] xy= new double[2];
Iterator
iterator = root.elementIterator();
while(iterator.hasNext()){
Element e = iterator.next();
if(e.getName().equals("node")){
StringBuilder sb = new StringBuilder();
//first get all node's attributes
List
list = e.attributes();
//traverse attributes
for(Attribute attribute : list){
if(attribute.getName().equals("id"))
sb.append(attribute.getValue()+" ");
if(attribute.getName().equals("lat")) {
latValue = Double.valueOf((attribute.getValue()).toString());;
sb.append(attribute.getValue()+" ");
}
// computer xy in MillerCoordinate from latitude and longitude
if(attribute.getName().equals("lon"))
{
sb.append(attribute.getValue()+" ");
lonValue = Double.valueOf((attribute.getValue()).toString());;
xy = MillerCoordinate.MillierConvertion(latValue, lonValue);
sb.append(xy[0]+" ");
sb.append(xy[1]+" ");
xy[0] = 0;
xy[1] = 0;
}
}
bwPoint.write(sb.toString()+"\r\n");
bwPoint.flush();
}
}
bwPoint.close();
oswPoint.close();
fosPoint.close();
System.out.println("output finish!");
}
}