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