您的位置:首页 > 其它

2.XML语言

2017-11-11 19:44 113 查看
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
4000
= 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 {
}

}

11e3a
例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);
}
}*/
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: