XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便。
对于XML本身的语法知识与技术细节,需要阅读相关的技术文献,这里面包括的内容有
DOM(Document Object Model),
DTD(Document Type Definition),
SAX(Simple API for XML),
XSD(Xml Schema Definition),
XSLT(Extensible Stylesheet Language Transformations),
具体可参阅w3c官方网站文档http://www.w3.org获取更多信息。
XML在不同的语言里解析方式都是一样的,只不过实现的语法不同而已。基本的解析方式有两种,一种叫SAX,另一种叫DOM。
SAX、DOM是两种对xml文档进行解析的方法(没有具体实现,只是接口),所以只有它们是无法解析xml文档的。
SAX是基于事件流的解析,DOM是基于XML文档树结构的解析,它们之间的具体区别可以参考我的这篇博文《XML解析的两种方式DOM和SAX》。
注意:这里我们说的四种解析方法,Jdom,dom4J属于dom方式实现的范畴。
假设我们XML的内容和结构如下:
<?xml version="1.0" encoding="UTF-8"?> <user> <!--注释--> <Account type="mobile"> <name>移动</name> <code>10086</code> <pass>123456</pass> <money>999999999</money> </Account> <Account type="unicom"> <name>联通</name> <code>10010</code> <pass>123456</pass> <money>88888888</money> </Account> </user>
public interface XmlDocument { /** * @see 建立XML文档 * @param fileName 文件全路径名称 */ public void createXml(String fileName); /** * @see 解析XML文档 * @param fileName 文件全路径名称 */ public void parserXml(String fileName); }
1.DOM生成和解析XML文档
由W3C提供的接口,它将整个XML文档读入内存,构建一个DOM树来对各个节点(Node)进行操作。
为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。
public class DomDemo { public void createXml(String fileName) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.newDocument(); Element root = document.createElement("user"); document.appendChild(root); //*******设置第一个******** Element accountElement = document.createElement("Account"); accountElement.setAttribute("type", "mobile"); Element name = document.createElement("name"); name.appendChild(document.createTextNode("移动")); accountElement.appendChild(name); Element code = document.createElement("code"); code.appendChild(document.createTextNode("10086")); accountElement.appendChild(code); Element pass = document.createElement("pass"); pass.appendChild(document.createTextNode("123456")); accountElement.appendChild(pass); Element money = document.createElement("money"); money.appendChild(document.createTextNode("999999999")); accountElement.appendChild(money); root.appendChild(accountElement); //设置第二个 Element accountElement2 = document.createElement("Account"); accountElement2.setAttribute("type", "unicom"); Element name2 = document.createElement("name"); name2.appendChild(document.createTextNode("联通")); accountElement2.appendChild(name2); Element code2 = document.createElement("code"); code2.appendChild(document.createTextNode("10010")); accountElement2.appendChild(code2); Element pass2 = document.createElement("pass"); pass2.appendChild(document.createTextNode("123456")); accountElement2.appendChild(pass2); Element money2 = document.createElement("money"); money2.appendChild(document.createTextNode("88888888")); accountElement2.appendChild(money2); root.appendChild(accountElement2); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); DOMSource source = new DOMSource(document); transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); PrintWriter pw = new PrintWriter(new FileOutputStream(fileName)); StreamResult result = new StreamResult(pw); transformer.transform(source, result); } public void parserXml(String fileName) throws Exception { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // 返回documentBuilderFactory对象 DocumentBuilder db = dbf.newDocumentBuilder();// 返回db对象用documentBuilderFatory对象获得返回documentBuildr对象 Document dt = db.parse(new File(fileName)); // 得到一个DOM并返回给document对象 Element root = dt.getDocumentElement();// 得到一个elment根元素 System.out.println("根元素:" + root.getNodeName()); // 获得根节点 NodeList childNodes = root.getChildNodes(); // 获得根元素下的子节点 for (int i = 0; i < childNodes.getLength(); i++) { // 遍历这些子节点 Node node = childNodes.item(i); // childNodes.item(i); 获得每个对应位置i的结点 if ("Account".equals(node.getNodeName())) {// 如果节点的名称为"Account",则输出Account元素属性type System.out.println("属性-所属区域: "+ node.getAttributes().getNamedItem("type").getNodeValue()); NodeList nodeDetail = node.getChildNodes(); // 获得<Accounts>下的节点 for (int j = 0; j < nodeDetail.getLength(); j++) { // 遍历<Accounts>下的节点 Node detail = nodeDetail.item(j); // 获得<Accounts>元素每一个节点 if ("code".equals(detail.getNodeName())) // 输出code { System.out.println("卡号: " + detail.getTextContent()); } else if ("pass".equals(detail.getNodeName())) // 输出pass { System.out.println("密码: " + detail.getTextContent()); } else if ("name".equals(detail.getNodeName())) // 输出name { System.out.println("姓名: " + detail.getTextContent()); } else if ("money".equals(detail.getNodeName())) // 输出money { System.out.println("余额: " + detail.getTextContent()); } } } } } }
2.SAX生成和解析XML文档
SAX不用将整个文档加载到内存,基于事件驱动的API(Observer模式),用户只需要注册自己感兴趣的事件即可。SAX提供EntityResolver, DTDHandler, ContentHandler, ErrorHandler接口,分别用于监听解析实体事件、DTD处理事件、正文处理事件和处理出错事件,与AWT类似,SAX还提供了一个对这4个接口默认的类DefaultHandler(这里的默认实现,其实就是一个空方法),一般只要继承DefaultHandler,重写自己感兴趣的事件即可。
public class SaxDemo implements XmlDocument{ public void parserXml(String fileName) throws Exception{ //获得SAX解析器工厂实例 SAXParserFactory factory = SAXParserFactory.newInstance(); //获得SAX解析器实例 SAXParser parser = factory.newSAXParser(); //开始进行解析 parser.parse(new File(fileName),new DefaultHandler(){ private Stack<String> stack = new Stack<String>(); private String name; private String code; private String pass; private String money; @Override public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException{ stack.push(qName); for(int i = 0;i<attributes.getLength();i++) { String attrName = attributes.getQName(i); String attrValue = attributes.getValue(i); System.out.println(attrName+"="+attrValue); } } @Override public void characters(char[] ch, int start, int length)throws SAXException{ String tag = stack.peek(); if("name".equals(tag)) { name = new String(ch,start,length); } else if("code".equals(tag)) { code = new String(ch,start,length); } else if("pass".equals(tag)) { pass = new String(ch,start,length); } else if("money".equals(tag)) { money = new String(ch,start,length); } } @Override public void endElement(String uri, String localName, String qName)throws SAXException{ stack.pop(); if("Account".equals(qName)) { System.out.println("姓名: "+name); System.out.println("卡号: "+code); System.out.println("密码 "+pass); System.out.println("余额: "+money); System.out.println(); } } }); } public void createXml(String fileName) { System.out.println(fileName); } }
3.DOM4J生成和解析XML文档
dom4j是目前在xml解析方面是最优秀的(Hibernate、Sun的JAXM也都使用dom4j来解析XML),它合并了许多超出基本 XML 文档表示的功能,包括集成的 XPath 支持、XML Schema 支持以及用于大文档或流化文档的基于事件的处理。
public class Dom4jDemo implements XmlDocument{ @SuppressWarnings("unchecked") public void parserXml(String fileName) throws Exception{ SAXReader reader = new SAXReader(); Document document = reader.read(new File(fileName)); Element root = document.getRootElement(); //**************************1********************************************* for (Iterator<Element> it = root.elementIterator(); it.hasNext();) { Element element = it.next(); if ("Account".equals(element.getName())) { String account = element.getName(); System.out.println("account:"+account); System.out.println("属性-所属区域: " + element.attributeValue("type")); //************************* //获取单个 //************************* System.out.println(element.elementText("code")); System.out.println(element.element("code").getText()); for(Iterator<Element> child = element.elementIterator(); child.hasNext();) { Element el = child.next(); if ("code".equals(el.getName())) // 输出code { System.out.println("卡号: " + el.getText()); } else if ("pass".equals(el.getName())) // 输出pass { System.out.println("密码: " + el.getText()); } else if ("name".equals(el.getName())) // 输出name { System.out.println("姓名: " + el.getText()); } else if ("money".equals(el.getName())) // 输出money { System.out.println("余额: " + el.getText()); } } System.out.println(); } } //**************************2********************************************* List<Element> accountList = root.elements("Account");//特指就传参 for (Iterator<Element> it = accountList.iterator(); it.hasNext();) { Element element = it.next(); String account = element.getName(); System.out.println("account:"+account); System.out.println("属性-所属区域: " + element.attributeValue("type")); List<Element> list = element.elements();//不特指就为空 for(Iterator<Element> child = list.iterator(); child.hasNext();) { Element el = child.next(); if ("code".equals(el.getName())) // 输出code { System.out.println("卡号: " + el.getText()); } else if ("pass".equals(el.getName())) // 输出pass { System.out.println("密码: " + el.getText()); } else if ("name".equals(el.getName())) // 输出name { System.out.println("姓名: " + el.getText()); } else if ("money".equals(el.getName())) // 输出money { System.out.println("余额: " + el.getText()); } } } } public void createXml(String filename) throws Exception{ //创建文档并设置文档的根元素节点:第一种方式 // Document document = DocumentHelper.createDocument(); // Element root = DocumentHelper.createElement("student"); // document.setRootElement(root); //创建文档并设置文档的根元素节点:第二种方式 Element rootElement = DocumentHelper.createElement("user"); //注释 rootElement.addComment("***************************"); Document document = DocumentHelper.createDocument(rootElement); //*******设置第一个******** Element accountElement = rootElement.addElement("Account"); //属性 accountElement.addAttribute("type", "mobile"); Element nameElement = accountElement.addElement("name"); nameElement.setText("移动"); Element codeElement = accountElement.addElement("code"); codeElement.setText("10086"); Element passElement = accountElement.addElement("pass"); passElement.setText("123456"); Element moneyElement = accountElement.addElement("money"); moneyElement.setText("999999999"); //*******设置第二个******** Element accountElement2 = rootElement.addElement("Account"); //属性 accountElement2.addAttribute("type", "mobile"); Element nameElement2 = accountElement2.addElement("name"); nameElement2.setText("联通"); Element codeElement2 = accountElement2.addElement("code"); codeElement2.setText("10010"); Element passElement2 = accountElement2.addElement("pass"); passElement2.setText("123456"); Element moneyElement2 = accountElement2.addElement("money"); moneyElement2.setText("88888888"); OutputFormat format = new OutputFormat(" ",true); XMLWriter writer = new XMLWriter(new FileOutputStream(new File(filename)),format); writer.write(document); writer.close(); } }
JDOM与DOM非常类似,它是处理XML的纯JAVA API,API大量使用了Collections类,且JDOM仅使用具体类而不使用接口。 JDOM 它自身不包含解析器。它通常使用 SAX2 解析器来解析和验证输入 XML 文档(尽管它还可以将以前构造的 DOM 表示作为输入)。它包含一些转换器以将 JDOM 表示输出成 SAX2 事件流、DOM 模型或 XML 文本文档.
public class JdomDemo implements XmlDocument{ public void parserXml(String fileName) throws Exception{ SAXBuilder bulider = new SAXBuilder(); Document doc = bulider.build(new File(fileName)); //获得根节点 Element root = doc.getRootElement(); System.out.println("根元素: "+root.getName()); //获得Account元素 // Element account = root.getChild("Account"); List<Element> accountList = root.getChildren("Account");//特指就传参 for(Iterator<Element> iter = accountList.iterator(); iter.hasNext();) { Element account = iter.next(); System.out.println("属性-所属区域: "+ account.getAttributeValue("type")); List<Attribute> listatr = account.getAttributes(); //循环遍历属性 for(Attribute data:listatr) { System.out.println("属性:"+data.getName()+" = "+data.getValue()); } List<Element> listele = account.getChildren();//不特指就为空 for (Element data:listele) { // 遍历<Accounts>下的节点 if ("code".equals(data.getName())) // 输出code { System.out.println("卡号: " + data.getText()); } else if ("pass".equals(data.getName())) // 输出pass { System.out.println("密码: " + data.getText()); } else if ("name".equals(data.getName())) // 输出name { System.out.println("姓名: " + data.getText()); } else if ("money".equals(data.getName())) // 输出money { System.out.println("余额: " + data.getText()); } } System.out.println(); } } public void createXml(String fileName) throws Exception{ Document document = new Document(); Element rootElement = new Element("user"); document.addContent(rootElement); Comment comment = new Comment("注释"); rootElement.addContent(comment); //*******设置第一个******** Element accountElement = new Element("Account"); accountElement.setAttribute("type","mobile"); rootElement.addContent(accountElement); Element name = new Element("name"); name.setText("移动"); accountElement.addContent(name); Element code = new Element("code"); code.setText("10086"); accountElement.addContent(code); Element pass = new Element("pass"); pass.setText("123456"); accountElement.addContent(pass); Element money = new Element("money"); money.setText("999999999"); accountElement.addContent(money); //*******设置第二个******** Element accountElement2 = new Element("Account"); accountElement2.setAttribute("type","unicom"); rootElement.addContent(accountElement2); Element name2 = new Element("name"); name2.setText("联通"); accountElement2.addContent(name2); Element code2 = new Element("code"); code2.setText("10010"); accountElement2.addContent(code2); Element pass2 = new Element("pass"); pass2.setText("123456"); accountElement2.addContent(pass2); Element money2 = new Element("money"); money2.setText("88888888"); accountElement2.addContent(money2); XMLOutputter out = new XMLOutputter(Format.getPrettyFormat()); out.output(document, new FileOutputStream(fileName)); } }
window.url.createobjecturl 兼容多个浏览器(IE,google,360,Safari,firefox),布布扣,bubuko.com
window.url.createobjecturl 兼容多个浏览器(IE,google,360,Safari,firefox)
原文:http://blog.csdn.net/ybb350680013/article/details/24006535