XML
eXtensible Markup Language,可扩展标记语言。
XML 被设计用来传输和存储数据,是独立于软件和硬件的信息传输工具。
XML简介
-
XML需要自定义标签。自定义的标签具有自我描述性。
-
XML不会做任何事情,只是传输信息。
-
可用于在HTML中显示动态数据,通过JavaScript语句读取外部XML文件。
-
XML的数据可跨平台访问。
-
用于创建新的互联网语言,如:XHTML、WSDL、RSS、OWL、SMIL等。
XML树结构
- 实例
<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
第一行是XML声明,<note>
是根元素,接下来的4行是4个子元素。
- 结构图
<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>
XML语法
-
必须要关闭标签
-
标签对大小写敏感
-
嵌套必须按顺序
-
必须要有根元素,有一个元素是所有其他元素的父元素。
-
属性值必须加引号
-
XML中部分字符不能用于元素中,需用实体引用来代替
< | < | less than |
---|---|---|
> | > | greater than |
& | & | ampersand |
' | ’ | apostrophe |
" | " | quotation mark |
虽然在 XML 中,只有字符 “<” 和 “&” 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。
- 注释的语法
<!-- This is a comment -->
-
XML中的所有空格会被保留,不会被缩减
-
在 Windows 应用程序中,换行通常以一对字符来存储:回车符(CR)和换行符(LF)。XML跟 Unix 和 Mac OSX 一样,使用 LF 来存储新行。
XML元素
-
XML元素可以包含:其他元素、文本、属性。
-
标签命名规则
-
- 可包含字符、数字以及其他字符
- 不能以数字或标点符号开始
- 不能以字母xml(或者XML、Xml等)开始
- 不能包含空格
-
命名习惯
-
- 具有描述性
- 恰当使用"_"
- 避免使用"-",软件可能识别为减号操作
- 避免使用".",软件会认为这名称包含一个属性,如“first.name”中name被认为是first的一个属性
- 避免使用":",冒号会被转换为命名空间来使用
- 可以是用非英语字母,但要注意软件是否支持。
-
可扩展:随时添加新的元素,不会对之前的结果产生影响。
XML属性
- XML属性通常不提供数据。下面的例子中,文件类型与数据内容无关,但对需要处理这个元素的软件来说很重要。
<file type="gif">computer.gif</file>
- 属性值包含引号,可以使用单引号,也可以使用字符实体。
<gangster name='George "Shotgun" Ziegler'>
- 如果信息感觉起来也很像数据,尽量使用元素,而不是属性。
<person>
<sex>female</sex>
<firstname>Anna</firstname>
<lastname>Smith</lastname>
</person>
<person sex="female">
<firstname>Anna</firstname>
<lastname>Smith</lastname>
</person>
- 使用扩展的元素
<date>10/01/2008</date>
<date>
<day>10</day>
<month>01</month>
<year>2008</year>
</date>
-
属性不能包含多个值,不能包含树结构,不能扩展。因此尽量使用元素来描述数据,使用属性来提供与数据无关的信息。
-
XML属性需要遵循的规则:
-
- 属性名称不能在同一起始标签或空元素标签中出现一次
- 一个属性必须使用属性表声明的文档类型定义(DTD)的声明
- 属性值不能包含直接或间接的实体引用外部实体
- 任何实体的替换文本称为直接或间接的属性值中不能包含任何小于号
XML DTD
DTD,Document Type Definition,文档类型定义,可用来定义XML的结构。
<?xml version="1.0" ?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<message>Don't forget me this weekend!</message>
</note>
XML Schema
一种基于 XML 的 DTD 代替者
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
XML和XSLT
XSLT,eXtensible Stylesheet Language Transformations,是首选的XML的XML样式表语言。XSLT 是在浏览器显示 XML 文件之前,先把它转换为 HTML。
- 当浏览器读取 XML 文件时,XSLT 转换是由浏览器完成的。
- 在使用 XSLT 来转换 XML 时,不同的浏览器可能会产生不同结果。为了减少这种问题,可以在服务器上进行 XSLT 转换。
XML解析器
XML 解析器用于检查 XML 文档的适当的格式,并且还可以验证 XML 文档。
XML 解析器把 XML 文档转换为 XML DOM 对象 - 可通过 JavaScript 操作的对象。
- 解析XML文档
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","books.xml",false);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;
- 解析XML字符串
txt="<bookstore><book>";
txt=txt+"<title>Everyday Italian</title>";
txt=txt+"<author>Giada De Laurentiis</author>";
txt=txt+"<year>2005</year>";
txt=txt+"</book></bookstore>";
if (window.DOMParser)
{
parser=new DOMParser();
xmlDoc=parser.parseFromString(txt,"text/xml");
}
else // Internet Explorer
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false;
xmlDoc.loadXML(txt);
}
//Internet Explorer 使用 loadXML() 方法来解析 XML 字符串,而其他浏览器使用 DOMParser 对象。
XML DOM
DOM(Document Object Model 文档对象模型)定义了访问和操作文档的标准方法。
XML DOM(XML Document Object Model)定义了访问和操作 XML 文档的标准方法。
XML DOM 把 XML 文档作为树结构来查看。
下面的实例把 XML 文档 note.xml 解析到 XML DOM 对象中,然后通过 JavaScript 提取一些信息。
<html>
<body>
<h1>W3Cschools Internal Note</h1>
<div>
<b>To:</b> <span id="to"></span><br />
<b>From:</b> <span id="from"></span><br />
<b>Message:</b> <span id="message"></span>
</div>
<script>
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","note.xml",false);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;
//getElementsByTagName方法返回一个数组
document.getElementById("to").innerHTML=
xmlDoc.getElementsByTagName("to")[0].childNodes[0].nodeValue;
document.getElementById("from").innerHTML=
xmlDoc.getElementsByTagName("from")[0].childNodes[0].nodeValue;
document.getElementById("message").innerHTML=
xmlDoc.getElementsByTagName("body")[0].childNodes[0].nodeValue;
</script>
</body>
</html>
XML to HTML
可以在 HTML 中读取 XML 格式文件,并将其所有内容都显示到 HTML 页面上,即显示标签内容,并且显示标签本身。
<html>
<body>
<script>
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","cd_catalog.xml",false);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;
document.write("<table border='1'>");
var x=xmlDoc.getElementsByTagName("CD");
for (i=0;i<x.length;i++)
{
document.write("<tr><td>");
document.write(x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue);
document.write("</td><td>");
document.write(x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue);
document.write("</td></tr>");
}
document.write("</table>");
</script>
</body>
</html>
DOM解析XML(Java方法)
把整个XML 文档加载到内存,转化成DOM 树,应用程序可以随机的访问DOM 树的任何数据。
优点:灵活性强,速度快
缺点:消耗资源比较多
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="001">
<name>张三</name>
<sex>男</sex>
<age>20</age>
</student>
<student id="002">
<name>李四</name>
<sex>女</sex>
<age>21</age>
</student>
</students>
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DOM02 {
//获取属性节点的信息
public static void printNodeAttr(Node node){
NamedNodeMap namedNodeMap=node.getAttributes();
for(int i=0;i<namedNodeMap.getLength();i++){
Node attrNode=namedNodeMap.item(i);
System.out.println(attrNode.getNodeName()+":"+attrNode.getFirstChild().getNodeValue());
}
}
public static void main(String[] args) {
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc=builder.parse("src/students.xml");
NodeList nodeList=doc.getElementsByTagName("students");
Element element=(Element)nodeList.item(0);
NodeList studentsNodeList=element.getElementsByTagName("student");
//循环遍历,获取文本节点和元素节点的信息
for(int i=0;i<studentsNodeList.getLength();i++){
Element e=(Element)studentsNodeList.item(i);
System.out.println("Name"+e.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
printNodeAttr(e.getElementsByTagName("name").item(0));
System.out.println("Sex"+e.getElementsByTagName("sex").item(0).getFirstChild().getNodeValue());
System.out.println("Age"+e.getElementsByTagName("age").item(0).getFirstChild().getNodeValue());
System.out.println("================");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
SAX解析XML(Java方法)
Simple API for XML,是个接口也是个软件包,是一个解析XML的替代方法。
SAX方法对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)
开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同
样的扫描,直至文档结束。
优点:消耗资源比较少;适合大文件解析;
缺点:只能读取不能修改;开发复杂;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.java1234.model.Student;
public class SAX02 extends DefaultHandler{
private List<Student> students=null;
private Student student=null;
private String preTag=null; // 标记上一个节点名称
@Override
public void startDocument() throws SAXException {
System.out.println("开始读取学生信息");
students=new ArrayList<Student>();
}
@Override
public void endDocument() throws SAXException {
System.out.println("\n 学生信息读取完毕");
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if("student".equals(qName)){
student=new Student();
student.setId(attributes.getValue(0));
}
preTag=qName;
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if("student".equals(qName)){
students.add(student);
student=null;
}
preTag=null;
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if(preTag!=null){
String content=new String(ch,start,length);
if("name".equals(preTag)){
student.setName(content);
}else if("sex".equals(preTag)){
student.setSex(content);
}else if("age".equals(preTag)){
student.setAge(Integer.parseInt(content));
}
}
}
public static void main(String[] args) throws Exception{
SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser parser=factory.newSAXParser();
SAX02 sax02=new SAX02();
parser.parse("src/students.xml", sax02);
for(Student s:sax02.students){
System.out.println(s);
}
}
}
服务器上的XML
如果你想要让浏览器能够访问 Web 项目,那么需要配置服务器里面的 Web.XML 文件。一旦配置不成功,浏览器就无法进行访问。
- 直接存储XML文件
- 通过ASP生成XML文件,保存到服务器
<%
response.ContentType="text/xml"
response.Write("<?xml version='1.0' encoding='ISO-8859-1'?>")
response.Write("<note>")
response.Write("<from>Jani</from>")
response.Write("<to>Tove</to>")
response.Write("<message>Remember me this weekend</message>")
response.Write("</note>")
%>
- 通过PHP生成XML响应
<?php
header("Content-type: text/xml");
echo "<?xml version='1.0' encoding='ISO-8859-1'?>";
echo "<note>";
echo "<from>Jani</from>";
echo "<to>Tove</to>";
echo "<message>Remember me this weekend</message>";
echo "</note>";
?>
- 从数据库生成XML
<%
response.ContentType = "text/xml"
set conn=Server.CreateObject("ADODB.Connection")
conn.provider="Microsoft.Jet.OLEDB.4.0;"
conn.open server.mappath("/db/database.mdb")
sql="select fname,lname from tblGuestBook"
set rs=Conn.Execute(sql)
response.write("<?xml version='1.0' encoding='ISO-8859-1'?>")
response.write("<guestbook>")
while (not rs.EOF)
response.write("<guest>")
response.write("<fname>" & rs("fname") & "</fname>")
response.write("<lname>" & rs("lname") & "</lname>")
response.write("</guest>")
rs.MoveNext()
wend
rs.close()
conn.close()
response.write("</guestbook>")
%>
- 通过XSLT转换XML
<%
'Load XML
set xml = Server.CreateObject("Microsoft.XMLDOM")
xml.async = false
xml.load(Server.MapPath("simple.xml"))
//创建微软 XML 解析器的实例(XMLDOM),并把 XML 文件载入内存。
'Load XSL
set xsl = Server.CreateObject("Microsoft.XMLDOM")
xsl.async = false
xsl.load(Server.MapPath("simple.xsl"))
//创建解析器的另一个实例,并把 XSL 文件载入内存。
'Transform file
Response.Write(xml.transformNode(xsl))
//使用 XSL 文档来转换 XML 文档,并把结果以 XHTML 发送到您的浏览器。
%>
- 通过ASP保存XML到服务器
<%
text="<note>"
text=text & "<to>Tove</to>"
text=text & "<from>Jani</from>"
text=text & "<heading>Reminder</heading>"
text=text & "<body>Don't forget me this weekend!</body>"
text=text & "</note>"
set xmlDoc=Server.CreateObject("Microsoft.XMLDOM")
xmlDoc.async=false
xmlDoc.loadXML(text)
xmlDoc.Save("test.xml")
%>
XML命名空间
命名空间是一组唯一的名称,该命名空间是确定的URI(统一资源标识符)。
XML 命名空间提供避免元素命名冲突的方法。
<root>
<h:table xmlns:h="http://www.w3.org/TR/html4/">
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
<f:table xmlns:f="//www.w3cschool.cn/furniture">
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>
-
命名空间是在元素的开始标签的 xmlns 属性中定义的。
命名空间声明的语法如下。xmlns:前缀=“URI”。
<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="//www.w3cschool.cn/furniture">
<!-- 也可以在根元素中定义 -->
</root>
-
命名空间 URI 不会被解析器用于查找信息。
其目的是赋予命名空间一个惟一的名称。不过,很多公司常常会作为指针来使用命名空间指向实际存在的网页,这个网页包含关于命名空间的信息。
-
XSLT 是一种用于把 XML 文档转换为其他格式的 XML 语言。
下面的 XSLT 文档中,您可以看到,大多数的标签是 HTML 标签,非 HTML 的标签都有前缀 xsl,并由此命名空间标识。
xmlns:xsl="http://www.w3.org/1999/XSL/Transform":
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr>
<th align="left">Title</th>
<th align="left">Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
JDOM
JDOM是一种使用 XML 的独特 Java 工具包,它的设计包含 Java 语言的语法乃至语义,用于快速开发 XML 应用程序
利用更为强有力的JAVA语言的诸多特性(方法重载、集合概念以及映射),把SAX和DOM的功能有效地结合起来。SAX没有文档修改、随机访问以及输出的功能,而对于DOM来说,JAVA程序员在使用时来用起来总觉得不太方便。
-
下载并添加jdom-2.0.6.jar
-
生成XML
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.XMLOutputter;
public class JDOM01 {
public static void main(String[] args) {
Element student=new Element("student");
//新元素,作为跟节点
Attribute id=new Attribute("id", "001");
Attribute aa=new Attribute("aa", "xx");
student.setAttribute(id);
student.setAttribute(aa);
Element name=new Element("name");
name.setText("Alan");
student.addContent(name);
//添加子节点
Element sex=new Element("sex");
sex.setText("male");
student.addContent(sex);
Element age=new Element("age");
age.setText("20");
student.addContent(age);
Document document=new Document(student);
XMLOutputter out=new XMLOutputter();
out.setFormat(out.getFormat().setEncoding("UTF-8"));
//生成XML文件
try {
out.output(document, new FileOutputStream("src/student2.xml"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- 读取XML
import java.util.List;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
public class JDOM02 {
public static void main(String[] args) throws Exception{
SAXBuilder builder=new SAXBuilder();
Document document=builder.build("src/students.xml");
Element students=document.getRootElement();
List studentList=students.getChildren("student");
for(int i=0;i<studentList.size();i++){
Element student=(Element)studentList.get(i);
String id=student.getAttributeValue("id");
String name=student.getChildText("name");
String sex=student.getChildText("sex");
String age=student.getChildText("age");
System.out.println("学号:"+id+";姓名:"+name+";性别:"+sex+";年龄:"+age);
}
}
}
DOM4J
dom4j 是一个Java 的XML API,类似于jdom,用来读写XML 文件的。dom4j 是一个非常非常优秀的JavaXML API,具有性能优异、功能强大和极端易用使用的特点。
dom4j 无论在哪个方面都是非常出色的。如今越来越多的Java 软件都在使用dom4j 来读写 XML,Hibernate 用它来读写配置文件。
- 下载并添加dom4j-2.1.1.jar
- 写XML
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
public class DOM4J01 {
public static void main(String[] args) {
Document document=DocumentHelper.createDocument();
Element studentElement=document.addElement("student");
studentElement.addAttribute("id", "001");
studentElement.addAttribute("aa", "xx");
Element name=studentElement.addElement("name");
name.setText("Alan");
Element sex=studentElement.addElement("sex");
sex.setText("male");
Element age=studentElement.addElement("age");
age.setText("20");
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
try {
XMLWriter writer=new XMLWriter(new FileOutputStream("src/student3.xml"),format);
writer.write(document);
writer.close();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- 读XML
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class DOM4J02 {
public static void main(String[] args) throws Exception{
SAXReader saxReader=new SAXReader();
Document document=saxReader.read("src/students.xml");
Element rootElement=document.getRootElement();
Iterator iter=rootElement.elementIterator();
while(iter.hasNext()){
Element studentElement=(Element)iter.next();
System.out.println("学号:"+studentElement.attributeValue("id"));
System.out.println("姓名:"+studentElement.elementText("name"));
System.out.println("性别:"+studentElement.elementText("sex"));
System.out.println("年龄:"+studentElement.elementText("age"));
System.out.println("=========");
}
}
}