XML文档基本认识和基于JAVA对简单解析
2017-06-18 20:37
561 查看
在实际项目中我们经常会需要用到垮平台通讯的情况,支持跨平台通讯的技术很多,用到的通讯使用的文本格式也很多,例如JSON和XML等。在这里浅谈下对XML的认识和简单的解析。
XML:可扩展的标记语言;Extend Markup Language,是以标记和子标记的方法描述对象,集合。
例如我们现在有这么一个实体类
那么我们用XML文件可以这么表示
一个标准的XML的组成格式
–version –文档符合XML 1.0规范,现在只有1.0
–encoding– 文档字符编码,默认为“UTF-8”
– standalone– 文档定义是否在一个文件内(没有DTD可以不定义)
standalone 定义了外部定义的 DTD 文件的存在性,no 表示这个 XML 文档不是独立的而是依赖于外部所定义的一个 DTD. 值 yes 表示这个 XML 文档是自包含的(self-contained)
XML中的空元素,表示标签直接没有内容。例如现在我们的XML中有money这么个元素
XML根元素
XML有严格的格式要求,对大小写和符号敏感,在XML中有有5个特殊符号需要转义
需要注意的是:
1. 转义序列各字符间不能有空格;
2. 转义序列必须以”;”结束;
3. 单独的&不被认为是转义开始;
4. 区分大小写。
如果不想用转义符,也可以使用CDATA标签,CDATA是不被解析的文件。文本内的标签不会被当做标记,实体不会被展开。
结构完整的XML文档
满足XML基本的语法规则,如果XMML文档不是良好的格式,就不能被引用程序和游览器正确识别和解析
语法规范
1. 必须有XML声明语句
2.必须有且只有一个根元素
3.标记大小写敏感
4. 属性值需用引号
5. 标记成对
6. 空标记记得关闭
7. 元素正确嵌套
有效的XML
有效的XML除了要满足XML规范外,还要满足相应的DTD和Schema定义的元素规则
有效的XML一定是格式良好的,但是格式良好的XML不一定是有效的
DTD
XML的解析技术有很多种这里只列举了两种
XML解析技术
文档对象模型(DOM),一种基于树结构的API
DOM解析
1.基于树状结构的API
2.整个XML文档必须在内存中解析和存储
3.客户端引用程序就可以随机访问这些对象
4. 大型文档为造成内存紧张
XML简单(SAX),一种事件驱动API
SAX
1.SAX提供一种用于解析XML文档的事件驱动模型
2.使用回调机制将事件通知应用程序
特点
1. 不必将整个文件加载到内存中,占用内存少
2. 不能对文档进行随机访问
3. SAX是只读的
4. 文档只能遍历一次
下面就基于SAX做一个简单的XML解析,这里我们用的dom4j这个jar来做解析
需要的jar
XML对应的实体Bean
一个简单的XML文件
读取并解析现有XML或XML字符串的简单方法
测试
控制台输出结果
创建一个XML文件,个人感觉这个方法貌似并没有多大用,因为格式一般都是写好了,存成文件或者在数据库中的。
测试
运行结果,成功生成了一个test.xml
其实也可以直接用字符串拼接的方式实现新增一个XML,然后用
Document document = DocumentHelper.parseText(xmlStr)方法把他转换为document对象输出成XML文件就可以了
修改一个现有的XML的方法,在实际的项目中,XML文件格式经常会以字符串的形式存在数据库中,这里我们以这种条件为前提,写个简单的方法,当传入一个XML字符串时,怎么实现修改
测试
运行结果
XML:可扩展的标记语言;Extend Markup Language,是以标记和子标记的方法描述对象,集合。
例如我们现在有这么一个实体类
public class Stutent { private int id; private String name; private String sex; }
那么我们用XML文件可以这么表示
<?xml version="1.0" encoding="utf-8"?> <Students> <student id="1"> <name>张三</name> <sex>男</sex> </student> <student id="2"> <name>李四</name> <sex>女</sex> </student> <student id="3"> <name>王五</name> <sex>男</sex> </student> </Students>
一个标准的XML的组成格式
–version –文档符合XML 1.0规范,现在只有1.0
–encoding– 文档字符编码,默认为“UTF-8”
– standalone– 文档定义是否在一个文件内(没有DTD可以不定义)
* stanalond="yes" * stanalone="no"
<?xml version="1.0" encoding="utf-8" stanalone="no">
standalone 定义了外部定义的 DTD 文件的存在性,no 表示这个 XML 文档不是独立的而是依赖于外部所定义的一个 DTD. 值 yes 表示这个 XML 文档是自包含的(self-contained)
XML中的空元素,表示标签直接没有内容。例如现在我们的XML中有money这么个元素
<money></money> <money?>
XML根元素
* 每个XML文档必须有有且只有一个根元素 * 根元素是一个完全包括文档中的其他素有元素的元素 * 所有元素都必须在根元素中定义
XML有严格的格式要求,对大小写和符号敏感,在XML中有有5个特殊符号需要转义
需要注意的是:
1. 转义序列各字符间不能有空格;
2. 转义序列必须以”;”结束;
3. 单独的&不被认为是转义开始;
4. 区分大小写。
&(逻辑与) & <(小于) < >(大于) > "(双引号) " '(单引号) '
如果不想用转义符,也可以使用CDATA标签,CDATA是不被解析的文件。文本内的标签不会被当做标记,实体不会被展开。
<![CDATA[ ********************** ]]>
结构完整的XML文档
满足XML基本的语法规则,如果XMML文档不是良好的格式,就不能被引用程序和游览器正确识别和解析
语法规范
1. 必须有XML声明语句
<?xml version="1.0" encoding="utf-8"?>
2.必须有且只有一个根元素
3.标记大小写敏感
4. 属性值需用引号
5. 标记成对
6. 空标记记得关闭
7. 元素正确嵌套
有效的XML
有效的XML除了要满足XML规范外,还要满足相应的DTD和Schema定义的元素规则
有效的XML一定是格式良好的,但是格式良好的XML不一定是有效的
DTD
<?xml version="1.0" encoding="GB2312" ?> <!DOCTYPE 家庭 [ <!--DOCTYPE定义根元素:家庭--> <!ELEMENT 家庭 (人+,家电*)> <!--ELEMENT表示描述元素:()表示定义元素的子元素--> <! ELEMENT 人 (#PCDATA)> <!--#PCDATA表示"人"元素,标签中间的内容为文本--> <!ELEMENT 家电 EMPTY> <!--EMPTY表示"家电"元素为空元素--> <!ATTLIST 人 <!--ATTLIST 表示定义元素的属性> 名字 CDATA #REQUIRED <!--CDATA 表示属性的内容为文本--> 性别 (男|女) #REQUIRED <!--#REQUIRED表示该属性必须书写--> 年龄 CDATA #REQUIRED 爱好 CDATA #IMPLIED <!--#IMPLIED表示该属性可有可无--> > <!ATTLIST 家电 名称 CDATA #REQUIRED 数量 CDATA #REQUIRED 说明 CDATA #IMPLIED > ]>
XML的解析技术有很多种这里只列举了两种
XML解析技术
文档对象模型(DOM),一种基于树结构的API
DOM解析
1.基于树状结构的API
2.整个XML文档必须在内存中解析和存储
3.客户端引用程序就可以随机访问这些对象
4. 大型文档为造成内存紧张
XML简单(SAX),一种事件驱动API
SAX
1.SAX提供一种用于解析XML文档的事件驱动模型
2.使用回调机制将事件通知应用程序
特点
1. 不必将整个文件加载到内存中,占用内存少
2. 不能对文档进行随机访问
3. SAX是只读的
4. 文档只能遍历一次
下面就基于SAX做一个简单的XML解析,这里我们用的dom4j这个jar来做解析
需要的jar
XML对应的实体Bean
package com.lovo.beans; import java.io.Serializable; /** * 测试用简单商品类 * @author WZH * */ public class Product implements Serializable{ private static final long serialVersionUID = 5801648617772990983L; //商品id private Long id; //商品名 private String name; //商品价格 private double price; //厂商 private String factory; public Product() { super(); // TODO Auto-generated constructor stub } public Product(Long id, String name, double price, String factory) { super(); this.id = id; this.name = name; this.price = price; this.factory = factory; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getFactory() { return factory; } public void setFactory(String factory) { this.factory = factory; } @Override public String toString() { return "Product [id=" + id + ", name=" + name + ", price=" + price + ", factory=" + factory + "]"; } }
一个简单的XML文件
<?xml version="1.0" encoding="utf-8"?> <shopping> <product code="1"> <name>薯片</name> <price>15</price> <factory>乐事</factory> </product> <product code="2"> <name>可乐</name> <price>3</price> <factory>可口可乐</factory> </product> </shopping>
读取并解析现有XML或XML字符串的简单方法
/** * 读取并解析XML文件方法 * @param xmlUrl 如果是读取本地工程文件使用此参数传入文件路径 * @param xml 如果是传入xml字符串使用此参数 * @return 解析后的XML字符串 */ public List<Product> readXML(String xmlUrl, String xml) { List<Product> list=new ArrayList<Product>(); FileInputStream inXml = null; Document doc = null; // 判断为需解析的XML为本地文件或xml字符串 try { if (xmlUrl !=null && !("".equals(xmlUrl))) { inXml = new FileInputStream(new File(xmlUrl)); SAXReader saxReader = new SAXReader(); // xml文档对应实体文档 doc = saxReader.read(inXml); } if (xml !=null &&!("".equals(xml))) { // 将xml格式字符串转化为DOM对象 doc = DocumentHelper.parseText(xml); } //获取shopping根元素下所有子元素 List<Element> elementList=doc.selectNodes("//shopping/product"); //以直接通过标签获取到XML的值 for (Element em : elementList) { Product temp=new Product(); //得到product标签的属性 temp.setId(Long.parseLong(em.attributeValue("code"))); //获取标签内文本值的方法 temp.setName(em.elementText("name")); temp.setPrice(Double.parseDouble(em.elementText("price"))); temp.setFactory(em.elementText("factory")); list.add(temp); } } catch (Exception e) { e.printStackTrace(); } finally { try { if(inXml != null){ inXml.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return list; }
测试
public static void main(String[] args) { XMLUtils util = new XMLUtils(); String src = "C:/shopping.xml"; System.out.println("------读取XML文件并解析-------"); System.out.println(util.readXML(src, null)); String xml = "<?xml version='1.0' encoding='utf-8'?>" + "<shopping><product code='1'>" + "<name>老坛酸菜</name><" + "price>3.5</price>" + "<factory>统一</factory>" + "</product><product code='2'>" + "<name>加多宝</name>" + "<price>6</price>" + "<factory>加多宝</factory>" + "</product>" + "</shopping>"; System.out.println("------读取XML格式字符串并解析-------"); System.out.println(util.readXML(null, xml)); }
控制台输出结果
创建一个XML文件,个人感觉这个方法貌似并没有多大用,因为格式一般都是写好了,存成文件或者在数据库中的。
/** * 创建一个XML实体文件的方法 * @param products 商品集合 * @param fileName 文件名 * @param src 文件保存地址 * @return true 创建成功,false 创建失败 */ public boolean createXMLFile(List<Product> products,String fileName,String src){ //默认创建成功 boolean flag = true; try { //创建document对象 Document document = DocumentHelper.createDocument(); //创建根节点 Element shoppingtElement = document.addElement("shopping"); //加入一行注释 shoppingtElement.addComment("这是一个商品的XML"); //循环添加商品子节点 for(int i = 0;i < products.size(); i++){ //为shipping加入一个子节点 Element product = shoppingtElement.addElement("product"); //为product添加一个code属性 product.addAttribute("code", String.valueOf(products.get(i).getId())); //为product添加子节点 Element name = product.addElement("name"); Element price = product.addElement("price"); Element factory = product.addElement("factory"); //给节点添加文本内容 name.setText(products.get(i).getName()); price.setText(String.valueOf(products.get(i).getPrice())); factory.setText(products.get(i).getFactory()); } //生成XML文件 OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); //判断保存目录是否存在 File path = new File(src); if(!path.exists()){ path.mkdirs(); System.out.println("-----文件目录不存在,创建对应目录------------"); } File xmlFile = new File(src+"\\"+fileName+".xml"); XMLWriter writer = new XMLWriter(new FileOutputStream(xmlFile), format); writer.write(document); writer.flush(); writer.close(); } catch (Exception e) { e.printStackTrace(); flag = false; } return flag; }
测试
public static void main(String[] args) { XMLUtils util = new XMLUtils(); List<Product> list=new ArrayList<Product>(); list.add(new Product(1L, "电脑", 7000, "联想")); list.add(new Product(2L, "手机", 6800, "苹果")); list.add(new Product(3L, "电视", 75000, "索尼")); System.out.println(util.createXMLFile(list, "test", "c:\\test")); }
运行结果,成功生成了一个test.xml
其实也可以直接用字符串拼接的方式实现新增一个XML,然后用
Document document = DocumentHelper.parseText(xmlStr)方法把他转换为document对象输出成XML文件就可以了
修改一个现有的XML的方法,在实际的项目中,XML文件格式经常会以字符串的形式存在数据库中,这里我们以这种条件为前提,写个简单的方法,当传入一个XML字符串时,怎么实现修改
/** * 根据XML字符串创建一个实体XML文件 * @param products 商品集合 * @param fileName 文件名 * @param src 文件保存地址 * @param xmlStr 传入的xml格式文件 * @return true 创建成功,false 创建失败 */ public boolean createXMLByStr(List<Product> products,String fileName,String src,String xmlStr){ //默认转换成功 boolean flag = true; try { //获取document对象 Document document = DocumentHelper.parseText(xmlStr); //获取shopping根元素下所有子元素 List<Element> elementList=document.selectNodes("//shopping/product"); if(products.size() > 0){ //模板中已经存在一条空白的标签,这里这么写是为了展现修改方法 Element em = elementList.get(0); em.addAttribute("code", String.valueOf(products.get(0).getId())); em.element("name").setText(products.get(0).getName()); em.element("price").setText(String.valueOf(products.get(0).getPrice())); em.element("factory").setText(products.get(0).getFactory()); } //如果超过一条数据需要向XML追加节点 if(products.size() > 1){ //获取product节点上级父节点 Element em = elementList.get(0).getParent(); //循环添加商品子节点 for(int i = 1;i < products.size(); i++){ //为shipping加入一个子节点 Element product = em.addElement("product"); //为product添加一个code属性 product.addAttribute("code", String.valueOf(products.get(i).getId())); //为product添加子节点 Element name = product.addElement("name"); Element price = product.addElement("price"); Element factory = product.addElement("factory"); //给节点添加文本内容 name.setText(products.get(i).getName()); price.setText(String.valueOf(products.get(i).getPrice())); factory.setText(products.get(i).getFactory()); } } //生成XML文件 OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); //判断保存目录是否存在 File path = new File(src); if(!path.exists()){ path.mkdirs(); System.out.println("-----文件目录不存在,创建对应目录------------"); } File xmlFile = new File(src+"\\"+fileName+".xml"); XMLWriter writer = new XMLWriter(new FileOutputStream(xmlFile), format); writer.write(document); writer.flush(); writer.close(); } catch (Exception e) { e.printStackTrace(); flag = false; } return flag; }
测试
public static void main(String[] args) { XMLUtils util = new XMLUtils(); List<Product> list=new ArrayList<Product>(); list.add(new Product(1L, "电脑", 6666, "联想")); list.add(new Product(2L, "手机", 7777, "苹果")); list.add(new Product(3L, "电视", 8888, "索尼")); String xml = "<?xml version='1.0' encoding='utf-8'?>" + "<shopping><product>" + "<name></name><" + "price></price>" + "<factory></factory>" + "</product>" + "</shopping>"; System.out.println(util.createXMLByStr(list, "test", "c:\\test",xml)); }
运行结果
相关文章推荐
- Java解析XML文档(简单实例)——dom解析xml
- 从头认识Spring-2.8 基于java注解的配置(基本没有xml)
- Java解析XML文档(简单实例)——dom解析xml
- java中利用dom4j对XML文档的创建、解析、查找、修改、保存等操作。
- java中用dom解析xml的经典入门级文档
- Java中XML文档的解析问题(已解决)
- 【原创】使用DOM解析XML文档示例(Java)
- Java解析XML文档——dom解析xml
- 使用DOM解析XML文档示例(Java)
- java解析zip文档,解决解析zip中解析xml和html文档流断的方法
- Java解析XML文档——dom解析xml (转载)
- 【Java–XML】JDOM解析XML字符串(非XML文档)
- Java中使用DOM来解析xml文档
- Java解析XML文档——dom解析xml (转载)
- java中用dom解析xml的经典入门级文档
- Java解析XML文档——dom解析xml
- Java解析XML文档——dom解析xml
- Java解析XML文档——dom解析xml
- java中用dom解析xml的经典入门级文档
- Java解析XML文档——dom解析xml (转载)