简述:XML 指可扩展标记语言(eXtensible Markup Language)。
XML 被设计用来传输和存储数据。
XML 很重要,也很容易学习。
什么是xml?
- XML 指可扩展标记语言(EXtensible Markup Language)。
- XML 是一种很像HTML的标记语言。
- XML 的设计宗旨是传输数据,而不是显示数据。
- XML 标签没有被预定义。您需要自行定义标签。
- XML 被设计为具有自我描述性。
- XML 是 W3C 的推荐标准。
XML和HTML之间的差异
XML 不是 HTML 的替代。
XML 和 HTML 为不同的目的而设计:
- XML 被设计用来传输和存储数据,其焦点是数据的内容。
- HTML 被设计用来显示数据,其焦点是数据的外观。
HTML 旨在显示信息,而 XML 旨在传输信息。
通过XML可以自己发明标签
例:
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
上面实例中的标签没有在任何 XML 标准中定义过(比如 <to>
和 <from>
)。这些标签是由 XML 文档的创作者发明的。
这是因为 XML 语言没有预定义的标签。
HTML 中使用的标签都是预定义的。HTML 文档只能使用在 HTML 标准中定义过的标签(如 <p>
、<h1>
等等)。
XML 允许创作者定义自己的标签和自己的文档结构。
DOM解析
DOM的全称是Document Object Model,也即文档对象模型。在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作。通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。
DOM接口提供了一种通过分层对象模型来访问XML文档信息的方式,这些分层对象模型依据XML的文档结构形成了一棵节点树。无论XML文档中所描述的是什么类型的信息,即便是制表数据、项目列表或一个文档,利用DOM所生成的模型都是节点树的形式。也就是说,DOM强制使用树模型来访问XML文档中的信息。由于XML本质上就是一种分层结构,所以这种描述方法是相当有效的。
DOM树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想。不过,由于DOM分析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问所带来的方便,因此,DOM分析器还是有很广泛的使用价值的。
优点:
1、形成了树结构,有助于更好的理解、掌握,且代码容易编写。
2、解析过程中,树结构保存在内存中,方便修改。
缺点:
1、由于文件是一次性读取,所以对内存的耗费比较大。
2、如果XML文件比较大,容易影响解析性能且可能会造成内存溢出。
1.首先使用文本文档新建一个xml文件(注意编码格式)
xml代码如下:
<?xml version='1.0' encoding='UTF-8' ?>
<root>
<hang>
<产品唯一ID>aab产品唯一ID</产品唯一ID>
<通用名>aa通用名</通用名>
<商品名>aa商品名</商品名>
<剂型>aa剂型</剂型>
<批准文号>aa批准文号</批准文号>
<规格>aa规格</规格>
<包装说明>aa包装说明</包装说明>
<包装单位>aa包装单位</包装单位>
<生产企业>aa生产企业</生产企业>
<大包装转换比>aa大包装转换比</大包装转换比>
<中包装转换比>aa中包装转换比</中包装转换比>
<备注>aa备注</备注>
<库存>aa库存</库存>
<供应价>aa供应价</供应价>
<是否上架>aa是否上架</是否上架>
</hang>
<hang>
<产品唯一ID>a121</产品唯一ID>
<通用名>b12</通用名>
<商品名>c231</商品名>
<剂型>dewrwer</剂型>
<批准文号>e324324</批准文号>
<规格>f45645</规格>
<包装说明>g4543</包装说明>
<包装单位>hq324e2</包装单位>
<生产企业>i76</生产企业>
<大包装转换比>j453</大包装转换比>
<中包装转换比>k4r43r</中包装转换比>
<备注>le4tr4</备注>
<库存>mq3e2</库存>
<供应价>nefrw</供应价>
<是否上架>o56</是否上架>
</hang>
</root>
2.通过java编写DOM解析程序
java源代码:
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DOMTest {
public static void main(String[] args) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();//创建一个DocumentBuilderFactory的对象
//创建一个DocumentBuilder的对象
try {
DocumentBuilder db = dbf.newDocumentBuilder();//创建DocumentBuilder对象
Document document = db.parse("F://123.xml");//通过DocumentBuilder对象的parser方法加载123.xml文件到当前项目下
NodeList bookList = document.getElementsByTagName("hang");//获取所有book节点的集合
System.out.println("一共有" + bookList.getLength() + "个产品"); //通过nodelist的getLength()方法可以获取bookList的长度
for (int i = 0; i < bookList.getLength(); i++) {//遍历每一个book节点
System.out.println("=================下面开始遍历第" + (i + 1) + "个产品的内容=================");
Node book = bookList.item(i); //通过 item(i)方法 获取一个book节点,nodelist的索引值从0开始
NamedNodeMap attrs = book.getAttributes();//获取book节点的所有属性集合
System.out.println("第 " + (i + 1) + "个产品共有" + attrs.getLength() + "个属性");
for (int j = 0; j < attrs.getLength(); j++) {//遍历hang的属性
Node attr = attrs.item(j);//通过item(index)方法获取hang节点的某一个属性
System.out.print("属性名:" + attr.getNodeName());//获取属性名
System.out.println("--属性值" + attr.getNodeValue());//获取属性值
}
NodeList childNodes = book.getChildNodes(); //解析hang节点的子节点
System.out.println("第" + (i+1) + "个产品共有" +
childNodes.getLength() + "个子节点");//遍历childNodes获取每个节点的节点名和节点值
for (int k = 0; k < childNodes.getLength(); k++) {
if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {//区分出text类型的node以及element类型的node
System.out.print("第" + (k + 1) + "个节点的节点名:" //获取了element类型节点的节点名
+ childNodes.item(k).getNodeName());
System.out.println("--节点值是:" + childNodes.item(k).getFirstChild().getNodeValue()); //获取了element类型节点的节点值
}
}
System.out.println("======================结束遍历第" + (i + 1) + "个产品的内容=================");
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果如下:
一共有2个产品
=================下面开始遍历第1个产品的内容=================
第 1个产品共有0个属性
第1个产品共有31个子节点
第2个节点的节点名:产品唯一ID--节点值是:aab产品唯一ID
第4个节点的节点名:通用名--节点值是:aa通用名
第6个节点的节点名:商品名--节点值是:aa商品名
第8个节点的节点名:剂型--节点值是:aa剂型
第10个节点的节点名:批准文号--节点值是:aa批准文号
第12个节点的节点名:规格--节点值是:aa规格
第14个节点的节点名:包装说明--节点值是:aa包装说明
第16个节点的节点名:包装单位--节点值是:aa包装单位
第18个节点的节点名:生产企业--节点值是:aa生产企业
第20个节点的节点名:大包装转换比--节点值是:aa大包装转换比
第22个节点的节点名:中包装转换比--节点值是:aa中包装转换比
第24个节点的节点名:备注--节点值是:aa备注
第26个节点的节点名:库存--节点值是:aa库存
第28个节点的节点名:供应价--节点值是:aa供应价
第30个节点的节点名:是否上架--节点值是:aa是否上架
======================结束遍历第1个产品的内容=================
=================下面开始遍历第2个产品的内容=================
第 2个产品共有0个属性
第2个产品共有31个子节点
第2个节点的节点名:产品唯一ID--节点值是:a121
第4个节点的节点名:通用名--节点值是:b12
第6个节点的节点名:商品名--节点值是:c231
第8个节点的节点名:剂型--节点值是:dewrwer
第10个节点的节点名:批准文号--节点值是:e324324
第12个节点的节点名:规格--节点值是:f45645
第14个节点的节点名:包装说明--节点值是:g4543
第16个节点的节点名:包装单位--节点值是:hq324e2
第18个节点的节点名:生产企业--节点值是:i76
第20个节点的节点名:大包装转换比--节点值是:j453
第22个节点的节点名:中包装转换比--节点值是:k4r43r
第24个节点的节点名:备注--节点值是:le4tr4
第26个节点的节点名:库存--节点值是:mq3e2
第28个节点的节点名:供应价--节点值是:nefrw
第30个节点的节点名:是否上架--节点值是:o56
======================结束遍历第2个产品的内容=================