XML是一门标记语言,由两部分组成。
主要作用是:配置信息和保存或传递数据
在WebServices分布式开发中,同样支持跨项目使用XML进行数据交互,其中w3c提出了一些 概念,容易混淆。
1) SOAP:简单对象访问协议,专门用来进行跨项目和跨语言数据交互的协议。
2) SOA:面向服务开发(编程)
分为头信息和主体信息
头信息中主要包括:版本信息,编码,规则 (xsd,dtd),样式文件(css,XSL)
主体信息中包含的就是具体的数据。
主体信息的数据规则:
1) 主体信息都是由Node节点组成的
2) 节点分为三类,节点包含name和value两个属性。
a) 元素节点Element,只有name,没有value
b) 属性节点Attribute,name和value都有。
c) 文本节点Text,只有value,没有name
3) 节点之间存在父子关系,按照树型结构排列
4) 一个节点最多只能有一个父节点
5) 如果一个节点没有父节点,则该节点称为根节点。
6) 一个XML中必须且只能有一个根节点。
7) 一个节点可以有多个子节点,只有元素节点可以拥有子节点。
8) 文本节点不能再包含子节点,因此也称为叶子节点(Leaf)
为了读取XML的内容,或通过程序建立XML文件,开发中需要使用一些操作类完成对XML数据的解析,常用的解析方式有三种:
1) DOM解析:w3c官方提供,所有语言都支持这种方式,将整个XML读取到内存里,形成树型结构进行解析,因此代码更容易理解,语法格式不像java平时的代码风格,因此不容易记。
2) SAX解析:SUN官方提供,逐行读取数据,占用的内存更小,但代码的编写方式很难理解,需要自己编写一个解析器对XML内容进行处理。
3) 第三方提供的其他方式:结合了以上两种方式的优点,改善了缺点,推出的第三方支持,常用的有:JDOM,dom4j
3.1.1、DOM解析
DOM解析中的各种方法,在js中都可以使用
先来看使用DOM解析读取XML,并取得里面内容的功能。
public static void parseMappingXML(String filePath) throws Exception { // 解析时必须先建立核心操作对象Document DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(new File(filePath));
// 先取得<class>元素的内容 NodeList classList = document.getElementsByTagName("class"); // 由于只有这一个节点,因此直接取得 Node classNode = classList.item(0); // 将该节点强制转型为元素节点 Element classElement = (Element) classNode; // 取得里面的属性 // System.out.println(classElement.getAttribute("name")); // System.out.println(classElement.getAttribute("table")); // System.out.println(classElement.getAttribute("schema"));
// 取得所有<property>节点 NodeList propertyList = document.getElementsByTagName("property"); for (int i = 0; i < propertyList.getLength(); i++) { Element propertyElement = (Element) propertyList.item(i); System.out.println(propertyElement.getAttribute("name") + " 0--> " + propertyElement.getAttribute("type")); }
}
public static void parseWebXML(String filePath) throws Exception { // 建立DOcument DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(new File(filePath));
// 找到文本节点外的元素节点,并取得 Element paramNameElement = (Element) document.getElementsByTagName( "param-name").item(0);
// 查找该节点下的子节点 // Text text = (Text) paramNameElement.getChildNodes().item(0); // 还有简化的方法 Text text = (Text) paramNameElement.getLastChild(); System.out.println(text.getNodeName() + " 0--> " + text.getNodeValue());
} |
Java程序一般不会编写解析的操作,因为该功能是JavaScript完成的,一般由Java根据传入的数据,完成XML文件的创建操作。
public static void createXML(String savePath) throws Exception { // 先准备一些要转换的数据 List<City> allCities = new ArrayList<City>(); City c = new City(); c.setId(1); c.setTitle("南通"); allCities.add(c); c = new City(); c.setId(2); c.setTitle("南京"); allCities.add(c); c = new City(); c.setId(3); c.setTitle("杭州"); allCities.add(c);
// 建立核心操作对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.newDocument();
// 建立元素节点,完成根节点 Element root = document.createElement("allCity"); // 循环建立各个子节点 Iterator<City> iter = allCities.iterator(); while (iter.hasNext()) { c = iter.next();
// 建立元素节点 Element cityElement = document.createElement("city"); Element idElement = document.createElement("id"); Element titleElement = document.createElement("title");
// 建立文本节点 Text idText = document.createTextNode(c.getId().toString()); Text titleText = document.createTextNode(c.getTitle());
// 确定父子关系 idElement.appendChild(idText); titleElement.appendChild(titleText); cityElement.appendChild(idElement); cityElement.appendChild(titleElement); root.appendChild(cityElement); } // 将root设置为根节点 document.appendChild(root);
// 进行保存操作 TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(); // 建立要导出的源文件 Source s = new DOMSource(document); // 设置导出的输出流 StreamResult result = new StreamResult(new File(savePath));
// 设置导出编码 t.setOutputProperty("encoding", "UTF-8"); // 完成导出 t.transform(s, result);
} |
JDOM解析
如果想使用JDOM,必须先找到其核心支持包,该包可以从MyEclipse安装目录下找到。
以下是解析的代码
public static void parseXML(String filePath) throws Exception { // 这里直接解析dom.xml文件 // 先通过SAX读取文件 SAXBuilder builder = new SAXBuilder(); Document document = builder.build(new File(filePath)); // 从根节点开始,逐层解析 Element root = document.getRootElement(); // 通过根节点查找下面的子节点 List<Element> allCities = root.getChildren("city"); // 循环找到每个city下的id和title的内容 Iterator<Element> iter = allCities.iterator(); while (iter.hasNext()) { Element e = iter.next(); System.out.println(e.getChildText("id") + " --> " + e.getChildText("title")); } } |
创建功能比DOM更简单一点:
public static void createXML(String savePath) throws Exception { List<City> allCities = new ArrayList<City>(); City c = new City(); c.setId(1); c.setTitle("南通"); allCities.add(c); c = new City(); c.setId(2); c.setTitle("南京"); allCities.add(c); c = new City(); c.setId(3); c.setTitle("杭州"); allCities.add(c);
Document document = new Document(); // 建立根节点 Element root = new Element("allCity");
// 循环建立各个子节点 Iterator<City> iter = allCities.iterator();
while (iter.hasNext()) { c = iter.next();
// 建立元素节点 Element cityElement = new Element("city"); Element idElement = new Element("id"); Element titleElement = new Element("title");
// 文本节点不需要单独建立,直接使用字符串处理. // 直接完成关系的设置 idElement.addContent(c.getId().toString()); titleElement.addContent(c.getTitle()); cityElement.addContent(idElement); cityElement.addContent(titleElement); root.addContent(cityElement); } // 设置根节点 document.setRootElement(root);
// 导出XML, 使用XMLOutputter类完成 XMLOutputter outputter = new XMLOutputter(); // 设置编码 outputter.setEncoding("UTF-8");
// 完成导出 outputter.output(document, new FileWriter(new File(savePath)));
}
|