1.概念:
1.XML:Extensible Markup Language,可擴展標記語言。
xml技術是w3c組織發佈的,目前推薦遵循的是w3c組織於2000年發佈的xml1.0規範。
2.對有關係的數據進行處理。
3.xml語言出現的根本目標在於描述有關係的數據。
在xml語言中,它允許用戶自定義標籤。一個標籤用於描述一段數據。
一個標籤可以分爲開始標籤和結束標籤,在開始標籤和結束標籤之間,又可以使用其他標籤描述其他數據。
以此來實現數據關係的描述。
2.xml常見應用
1.xml技術除用於保存有關係的數據之外,還經常用作軟件配置文件,以描述程序模塊之間的關係。
2.在一個軟件系統中,爲提高系統的靈活性,它所啓動的模塊通常由其配置文件決定。
例如:一個軟件在啓動時,它需要啓動A,B兩個模塊,而A,B兩個模塊在啓動時,又分別需要A1,A2和B1,2
模塊的支持,爲了準確描述這種關係,用xml最合適。
3.xml語法:
文檔聲明,元素,屬性,註釋,CDATA區、特殊字符,處理指令。
1.文檔聲明
<?xml version="1.0" ?>
<?xml version="1.0" encoding="GB2312" ?>記事本可能會出現亂碼問題
<?xml version="1.0" encoding="GB2312" standalone="yes" ?>說明文檔是否獨立
2.元素:
①指xml文件中出現的標籤,一個標籤分爲開始標籤和結束標籤,一個標籤有如下幾種書寫形式:
包含標籤體:<a>www.baidu.com</a>
不包含標籤體:<a></a>,簡寫爲<a/>
②一個標籤中也可以嵌套若干子標籤。但所有標籤必須合理的嵌套,絕不允許交叉嵌套,如:
<a>welcome to <b> beijing </a></b>
③格式良好的xml文檔必須有且僅有一個根標籤,其他標籤都是這個根標籤的子孫標籤。
④對於xml標籤中出現的所有空行和換行,xml解析程序都會當作標籤內容進行處理,如:
⑤由於在xml中,空行和換行都作爲原始內容被處理,所以在編寫xml文件時,使用換行和縮進等方式讓原文件
中的內容清晰可讀的“良好”書寫習慣可能要被迫改變。
⑥一個xml元素可以包含字母,數字以及其他一些可見字符,但必須遵循下面的一些規範:
區分大小寫
不能以數字或下劃線“_”開頭
不能以xml開頭
不能包含空格
名稱中間不能含有冒號“:”
3.屬性:
①一個標籤可以有多個屬性,每個屬性都有它自己的名稱和取值。<input name="text">
②屬性值要用 雙引號 或 單引號 引起來
③定義屬性必循遵循與標籤相同的命名規範
④在xml技術中,標籤屬性所代表的信息,也可以被改成用子元素的形式來描述:
<input>
<name>text</name>
</input>
4.註釋:
①xml文件中的註釋格式:<!--註釋-->
②注意:
xml聲明之前不能有註釋
註釋不能嵌套
5.CDATA區(給程序看)
①在編寫xml文件時,有些內容可能不想讓解析引擎解析執行,而是當作原始內容處理。
②可以把這些內容放在CDATA區裏,對於CDATA區域內的內容,xml解析程序不會處理,而是直接原封不動的輸出。
③語法:<![CDATA[ 內容 ]]>
6.轉義字符(給人看)
對於一些單個字符,若想顯示其原始樣式,可以使用轉義的形式予以處理:
& &
< <
> >
" "
' '
7.處理指令
①處理指令,簡稱PI。處理指令用來指揮解析引擎如何解析xml文檔內容。
如:在xml文檔中可以使用xml=stylesheet指令,通知xml解析引擎,因用css文件顯示xml文檔內容
<?xml-stylesheet type="text/css" href="1.css"?>
②處理指令必須<? 開頭,?>結尾,xml聲明語句就是最常見的一種處理指定。
4.xml約束:
DTD,Schema
5.xml編程:Jaxp, JDom, Dom4j解析xml
1.1Jaxp:
使用Jaxp對xml文檔進行dom解析
DOM解析編程:
遍歷所有結點
查找某一個結點
刪除結點
更新結點
添加結點
jvm內存設置: -Xmx80m
示例:
//使用dom方法對xml文檔進行crud
public class Demo1 {
//讀取xml文檔中:<書名>JavaScript網頁開發</書名> 結點中的值
@Test
public void read1() throws Exception{
//1.創建工廠
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//2.得到dom解析器
DocumentBuilder builder = factory.newDocumentBuilder();
//3.解析xml文檔,得到代表文檔的document
Document document = builder.parse("src/book.xml");
NodeList list = document.getElementsByTagName("書名");
Node node = list.item(1);
String content = node.getTextContent();
System.out.println(content);
}
//遍歷所有標籤
@Test
public void read2() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
//得到根節點
Node root =document.getElementsByTagName("書架").item(0);
list(root);
}
private void list(Node node) {
if(node instanceof Element)
System.out.println(node.getNodeName());
NodeList list = node.getChildNodes();
for(int i=0; i<list.getLength();i++){
Node child = list.item(i);
list(child);
}
}
//得到xml文檔中標籤屬性的值:<書名 name="xxxxx">Java就業培訓教程</書名>
@Test
public void read3() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
//將Node強轉成子類Element,有更多的方法
Element bookname =(Element)document.getElementsByTagName("書名").item(0);
String value = bookname.getAttribute("name");
System.out.println(value);
}
//向xml文檔中添加結點:<售價>39.00元</售價>
@Test
public void add() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
//創建結點
Element price = document.createElement("售價");
price.setTextContent("39.00元");
//把創建的結點掛到第一本書上
Element book =(Element)document.getElementsByTagName("書").item(0);
book.appendChild(price);
//把更新後的內存寫回到xml文檔
TransformerFactory tffactory = TransformerFactory.newInstance();
Transformer tf = tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}
//向xml文檔中指定位置添加結點:<售價>39.00元</售價>
@Test
public void add1() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
//創建結點
Element price = document.createElement("售價");
price.setTextContent("39.00元");
//得到參考結點
Element refNode = (Element)document.getElementsByTagName("售價").item(0);
//得到要掛子結點的結點
Element book =(Element)document.getElementsByTagName("書").item(0);
//往book結點的指定未知插子節點
book.insertBefore(price, refNode);
//把更新後的內存寫回到xml文檔
TransformerFactory tffactory = TransformerFactory.newInstance();
Transformer tf = tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}
//向xml文檔標籤添加屬性:<書名 color="red">Java就業培訓教程</書名>
@Test
public void add2() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
//得到要添加屬性的結點
Element bookname =(Element)document.getElementsByTagName("書名").item(0);
//往bookname結點添加屬性
bookname.setAttribute("color", "red");
//把更新後的內存寫回到xml文檔
TransformerFactory tffactory = TransformerFactory.newInstance();
Transformer tf = tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}
//刪除標籤:<售價>29.5元</售價>
@Test
public void delete() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
//得到要刪除的結點
Element e =(Element)document.getElementsByTagName("售價").item(0);
e.getParentNode().removeChild(e);
//e.getParentNode().getParentNode().removeChild(e.getParentNode()); //刪除爸爸
//e.getParentNode().getParentNode().getParentNode().removeChild(e.getParentNode().getParentNode());//刪除整個xml
/* //得到刪除結點的爸爸
Element book =(Element)document.getElementsByTagName("書").item(0);
//爸爸刪除兒子
book.removeChild(e);*/
//把更新後的內存寫回到xml文檔
TransformerFactory tffactory = TransformerFactory.newInstance();
Transformer tf = tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}
//更新標籤:<售價>29.5元</售價> -> <售價>50元</售價>
@Test
public void update() throws Exception{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("src/book.xml");
//得到要更新的結點
Element e =(Element)document.getElementsByTagName("售價").item(0);
e.setTextContent("50元");
//把更新後的內存寫回到xml文檔
TransformerFactory tffactory = TransformerFactory.newInstance();
Transformer tf = tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?><書架>
<書>
<書名 color="red">Java就業培訓教程</書名>
<作者>張孝祥</作者>
<售價>50元</售價>
</書>
<書>
<書名>JavaScript網頁開發</書名>
<作者>張孝祥</作者>
<售價>28.00元</售價>
</書>
</書架>
案例:用xml作爲持久化設備實現考生成績管理系統
代碼
1.2 Jaxp
使用Jaxp對xml文檔進行sax解析:
sax解析:
①在使用DOM解析XML文檔時,需要讀取整個XML文檔,在內存中架構代表整個DOM樹的Decument對象,從而再對XML文檔進行操作。此種情況下,如果XML文檔特別大,就回消耗計算機大量內存,並且導致內存溢出。
②SAX解析允許在讀取文檔的時候,即對文檔進行處理,而不必等到整個文檔裝載完纔會對文檔進行操作。
原理:
例1:
public class Demo2 {
/*
sax解析xml文檔
*/
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//1.創建解析工廠
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.得到解析器
SAXParser sp = factory.newSAXParser();
//3.得到讀取器
XMLReader reader = sp.getXMLReader();
//4.設置內容處理器
reader.setContentHandler(new ListHander());
//5.讀取xml文檔內容
reader.parse("src/book.xml");
}
}
//得到xml文檔所有內容
class ListHander implements ContentHandler{
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
System.out.print("<"+qName);
for(int i=0; atts!=null && i<atts.getLength();i++){
String attName = atts.getQName(i);
String attValue = atts.getValue(i);
System.out.print(" "+attName+"=\""+attValue+"\"");
}
System.out.print(">");
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.print(new String(ch,start,length));
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.print("</"+qName+">");
}
@Override
public void endDocument() throws SAXException {
}
@Override
public void setDocumentLocator(Locator locator) {
}
@Override
public void startDocument() throws SAXException {
}
@Override
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
}
@Override
public void processingInstruction(String target, String data)
throws SAXException {
}
@Override
public void skippedEntity(String name) throws SAXException {
}
}
例2:
public class Demo1 {
/*
sax解析xml文檔
*/
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//1.創建解析工廠
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.得到解析器
SAXParser sp = factory.newSAXParser();
//3.得到讀取器
XMLReader reader = sp.getXMLReader();
//4.設置內容處理器
reader.setContentHandler(new TagValueHander());
//5.讀取xml文檔內容
reader.parse("src/book.xml");
}
}
//得到xml文檔指定標籤的內容
class TagValueHander extends DefaultHandler{
private String currentTag; //記住當前解析到的是什麼標籤
private int needNum = 2; //記住想獲取第幾個作者標籤的值
private int currentNum; //當前解析到的是第幾個
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentTag = qName;
if(currentTag.equals("作者")){
currentNum++;
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentTag =null;
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if("作者".equals(currentTag) && currentNum==needNum){
System.out.println(new String(ch,start,length));
}
}
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?><書架>
<書>
<書名 color="red">Java就業培訓教程</書名>
<作者>張孝祥</作者>
<售價>50元</售價>
</書>
<書>
<書名>JavaScript網頁開發</書名>
<作者>裏貨撒</作者>
<售價>28.00元</售價>
</書>
</書架>
sax解析案例:javabean封裝xml文檔數據
public class Demo1 {
/*
sax解析xml文檔
*/
@SuppressWarnings("rawtypes")
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//1.創建解析工廠
SAXParserFactory factory = SAXParserFactory.newInstance();
//2.得到解析器
SAXParser sp = factory.newSAXParser();
//3.得到讀取器
XMLReader reader = sp.getXMLReader();
//4.設置內容處理器
BeanListHander hander = new BeanListHander();
reader.setContentHandler(hander);
//5.讀取xml文檔內容
reader.parse("src/book.xml");
List list = hander.getBooks();
System.out.println(list);
}
}
//把xml文檔中的每一本書封裝到一個book對象,並把多個book對象放在一個list集合中返回。
class BeanListHander extends DefaultHandler{
private List list = new ArrayList();
private String currentTag;
private Book book;
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentTag =qName;
if("書".equals(currentTag)){
book =new Book();
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if("書名".equals(currentTag)){
String name = new String(ch,start,length);
book.setName(name);
}
if("作者".equals(currentTag)){
String author = new String(ch,start,length);
book.setAuthor(author);
}
if("售價".equals(currentTag)){
String price = new String(ch,start,length);
book.setPrice(price);
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentTag =null; //①不置null,會導致書名,作者,售價都被標籤之間的空行覆蓋。
//因爲這些空行也屬於內容,而再次進入內容判斷的時候,currentTag不置null的話,
//會繼續賦值。
//②並且到第一個書對象結束時,會引發空指針異常。因爲book置空了,
//但是內容判斷標誌currentTag沒有指控,會繼續給book賦值。
if("書".equals(qName)){
list.add(book);
book = null;
}
}
public List getBooks() {
return list;
}
}
2.dom4j 解析xml文檔
示例:
public class Demo1 {
//讀取xml文檔第二本書的:<書名>JavaScript網頁開發</書名>
@Test
public void read() throws DocumentException{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));
Element root = document.getRootElement();
Element book = (Element)root.elements("書").get(1);
String value = book.element("書名").getText();
System.out.println(value);
}
//讀取xml文檔第二本書的:<書名>JavaScript網頁開發</書名>
@Test
public void readAttr() throws DocumentException{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));
Element root = document.getRootElement();
Element book = (Element)root.elements("書").get(1);
String value = book.element("書名").attributeValue("name");
System.out.println(value);
}
//在第一本書添加一個新的售價:<售價>209元</售價>
@Test
public void add() throws DocumentException, IOException{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));
Element book = document.getRootElement().element("書");
book.addElement("售價").setText("209元");
//保存數據的亂碼問題
/* XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream("src/book.xml"),"UTF-8" ));
writer.write( document ); //document本身是utf-8
writer.close();*/
// 解決方法二:設置格式化輸出器,通過輸出格式設置輸出編碼表
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("gbk"); //把document設置成是gbk
// XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream("src/book.xml"),"gbk" ),format);
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write( document );
writer.close();
}
//在第一本書指定位置上添加一個新的售價:<售價>209元</售價> 更改保存了所有孩子的list集合是順序
@Test
public void add2() throws DocumentException, IOException{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));
Element book = document.getRootElement().element("書");
List list = book.elements();
Element price = DocumentHelper.createElement("售價");
price.setText("309元");
list.add(2,price);
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write( document );
writer.close();
}
//刪除上面添加的售價結點
@Test
public void delete() throws DocumentException, IOException{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));
Element price = document.getRootElement().element("書").element("售價");
price.getParent().remove(price);
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write( document );
writer.close();
}
//更新第二本書的作者
@Test
public void update() throws DocumentException, IOException{
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));
Element book = (Element) document.getRootElement().elements("書").get(1);
book.element("作者").setText("惑黎明");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write( document );
writer.close();
}
}
XPath提取xml文檔數:
1.XPath的語法:
查文檔
2.示例:
public class Demo2 {
/*
應用xpath提取xml文檔數據
*/
public static void main(String[] args) throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/book.xml"));
String value = document.selectSingleNode("//作者").getText();
System.out.println(value);
}
}
3.需求:用戶登陸
public class Demo3 {
/*
查找uers.xml文檔是否有和用戶相匹配的用戶名和密碼
*/
public static void main(String[] args) throws DocumentException {
String username = "aaa";
String password = "123";
//檢測xml文檔是否有匹配的用戶名和密碼
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/user.xml"));
Node node = document.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']");
if(node==null){
System.out.println("用戶名或密碼錯誤!");
}else{
System.out.println("登陸成功!");
}
}
}
6.xml約束:XML Schema技術
和DTD的比較:
入門:
Schema中:名稱空間:
xml中:引入名稱空間XML Schema具體位置:
xml中:引入默認名稱空間:
xml中:引入多個名稱空間XML Schema:
不使用名稱空間引入XML Schema文檔:(不用,瞭解)
7.Schema語法
查看文檔
XML Schema案例:
shiporder.xsd:默認名稱空間
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/shiporder"
elementFormDefault="qualified">
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string" />
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="address" type="xs:string" />
<xs:element name="city" type="xs:string" />
<xs:element name="country" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string" />
<xs:element name="note" type="xs:string" minOccurs="0" />
<xs:element name="quantity" type="xs:positiveInteger" />
<xs:element name="price" type="xs:decimal" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>
shiporder.xml:引入默認名稱空間XML Schema具體位置
<?xml version="1.0" encoding="UTF-8"?>
<shiporder xmlns="http://www.example.org/shiporder"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/shiporder shiporder.xsd"
orderid="111">
<orderperson>xxx</orderperson>
<shipto>
<name>xxx</name>
<address>xxx</address>
<city>xxx</city>
<country>xxx</country>
</shipto>
<item>
<title>xxx</title>
<quantity>12</quantity>
<price>5.2</price>
</item>
</shiporder>
8.面試題:平面圖形題( 二維數組 )
//打印M
public class Demo {
public static void main(String[] args) {
int num =64; //M擴大一次必須加4
int h = (num/4)+1; //M的高
int[][] arr = new int[h][num];
/* Arrays.fill(arr[0], ' ');
Arrays.fill(arr[1], ' ');
Arrays.fill(arr[2], ' ');*/
int x = h-1;
int y = 0;
boolean order = false;
for(int i=1;i<=num;i++){
arr[x][y] = i;
y++;
if(x == 0){
order = true;
}
if(x ==h-1){
order = false;
}
if(!order){
x--;
}
if(order){
x++;
}
}
for(int i=0; i< arr.length;i++){
for(int j=0; j<arr[i].length; j++){
if(arr[i][j] == 0){
System.out.print(" "); //幾位數加幾個空格,自己調整
}else{
System.out.print(arr[i][j]);
}
}
System.out.println();
}
/* arr[0][2] ='3';
arr[0][6] = '7';
arr[0][8] = '\n';
arr[1][1] = '2';
arr[1][3] = '4';
arr[1][5] = '6';
arr[1][7] = '8';
arr[1][8] = '\n';
arr[2][0] = '1';
arr[2][4] = '5';
arr[2][8] = '9';*/
/* for(char[] a:arr){
for(char b:a){
System.out.print(b);
}
}*/
}
}