java xml文件操作

来源:互联网 发布:招数据员要求 编辑:程序博客网 时间:2024/05/16 13:41

 

1.  XMl&dom_sax_dom4j

Html不能自己定义标签;本身缺少一些含义;它没有真正的国际化

Html->xhtml->xml

Xml : extensiable markup language 可扩展标记语言

Xml可以用来传送数据;做配置文件;xml文件还可以描述很复杂的数据关系(家谱)

                   还可以充当小型数据库

Xml语法

(1)     文档声明

<?xml version=”1.0” encoding=”编码方式”standalone=”yes|no”?>

(2)     一个xml 文档中,有且只有一个根元素

 

元素==标签==节点

(3)     在xml中

<name>xiaoming</name>

不等价与==

<name>

xiaoming

</name>

(4) 属性值用双引号(")或单引号(')分隔(如果属性值中有',用"分隔;有",用'分隔)

特别说明: 如果属性值有单引号,有双引号,则需要使用实体: html->&nbsp; &copy;

 

&lt;

&gt;

&amp;

&

&quot;

"

&apos;

'

 

 

<stuid="a&quot;0&apos;0&apos;1">

<name>杨过</name>

<sex>男</sex>

<age>30</age>

</stu>

(4)     CDATA节

有时我们希望传递一些特殊字符, <>@!#$%^&*( 可以使用 CDATA节包括

基本用法:

<intro><![CDATA[这个是好$$128qw8o8<Lk;>;akdf0sa98u329408><<K>>>学生]]></intro>

 

面试题:

问; 如何适用xml 去传递小图片

答:可以把文件读取成一个   byte[] ,然后放到  CDATA节,再传递.

 

(5)     处理指令

 

看一个案例:

<?xml version="1.0"encoding="utf-8"?>

<?xml-stylesheet href="my.css"type="text/css"?>

<class>

<!--学生信息-->

<stuid="a&quot;0&apos;0&apos;1&lt;" >

<name>杨过</name>

<sex>男</sex>

<age>30</age>

</stu>

<stu id="a002">

<name>李莫愁</name>

<sex>女</sex>

<age>20</age>

</stu>

</class>

 

my.css

name{

 font-size:100px;

 font-weight:bold;

 color:red;

}

sex{

 font-size:50px;

 font-weight:bold;

 color:blue;

}

age{

          font-size:20px;

 font-weight:bold;

 color:green;

 

}

Xml语法小结

XML声明语句

<?xml version="1.0"encoding="gb2312"?>

–  必须有且仅有一个根元素

–  标记大小写敏感

–  属性值用引号

–  标记成对

–  空标记关闭

–  元素正确嵌套

–  名称中可以包含字母、数字或者其它字符

–  名称中不能含空格 测

–  名称中不能含冒号(注:冒号留给命名空间使用)测

Dtd解析

和xml配合使用来约束xml;来解决xml过于自由问题

 

Dtd基本语法:

<!ELEMENT元素名 类型>

 

xml:

 

<?xmlversion="1.0" encoding="utf-8"?>

<!--引入dtd去约束该xml文件-->

<!DOCTYPE班级 SYSTEM "myClass2.dtd">

<班级>

         <学生>

                   <名字>周星驰</名字>

                   <年龄>23</年龄>

                   <介绍>学习刻苦</介绍>

         </学生>

         <学生>

                   <名字>林青霞</名字>

                    <年龄>32</年龄>

                   <介绍>是一个好学生</介绍>

         </学生>

</班级>

 

myClass2.dtd

<!ELEMENT班级 (学生+)>

<!ELEMENT学生 (名字,年龄,介绍)>

<!ELEMENT名字 (#PCDATA)>

<!ELEMENT年龄 (#PCDATA)>

<!ELEMENT介绍 (#PCDATA)>

 

完成校验的html

<html>

<head>

<!--自己编写一个简单的解析工具,去解析xml dtd 是否配套-->

<scriptlanguage="javascript">

<!--

         var xmldoc = newActiveXObject("Microsoft.XMLDOM");

         xmldoc.validateOnParse ="true";//开启校验

         xmldoc.load("myClass2.xml");//指定校验哪个xml文件

         document.writeln("错误信息是:"+xmldoc.parseError.reason+"<br/>"); 

         document.writeln("错误的行是:"+xmldoc.parseError.line);

 

//-->

</script>

</head>

<body>

</body>

</html>

 

Dtd的细节

 1dtd的分类:

内部DTD文档

         <!DOCTYPE根元素  [定义内容]>

外部DTD文档

         <!DOCTYPE根元素  SYSTEM "DTD文件路径">

2 xml引入dtd的两种方法

1.      引入本地 dtd

<!DOCTYPE 根元素 SYSTEM ‘地址’>

2.      引入公共的 dtd

p<!DOCTYPE 根元素PUBLIC  ‘地址’>

3

<!ELEMENT 元素名类型>

类型:

EMPTY, ANY , #PCDATA

(1)     dtd的修饰符


属性的细节

                   基本语法

<!ATTLIST 元素名

属性名类型  特点

.....

类型有五种

         CDATA 表示可以放入文本

ID   表示属性的值,不能重复,同时不要用数字开头.

IDREF/IDREFS   当一个元素的属性值,需要去引用另外一个ID ,则使用IDREF,如果希望引用多个,则使用IDREFS,请用空格隔开.

Enumerated  表示属性的值,只能是例举出了 比如

<!ATTLIST 学生

  地址 CDATA #FIXED "北京"

  学号 ID #REQUIRED

  大哥 IDREFS #REQUIRED

  性别 (男|女) #REQUIRED

ENTITY

 

         属性的特点有四种

#REQUIRED  表示必须有

#IMPLIED 表示可以有

#FIXED “值” 表示如果有,则必须是什么

Default “值” 表示如果不指定,则默认.

 

u  实体(ENTITY)

 

就是实体用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容

java :

String str=”你好”;

定义str,在别的地方,我们使用str就可以访问到  ‘你好’

 

引用实体

案例

在 dtd 中定义:

<!ENTITY mycopy "我的公司版权">

说明:最好把定义放在dtd的最后

在xml中使用

&mycopy;

 

参数实体

 

基本语法

<!ENTITY %  实体名字 ”实体内容”>

引用

%实体名字;

举例:

<!ELEMENT 班级 (学生*)>

<!ENTITY % myname "名字">

<!ELEMENT 学生 (%myname;,介绍,年龄)>

<!ATTLIST 学生

   地址 CDATA #FIXED "北京"

   学号 ID #REQUIRED

   大哥 IDREFS #REQUIRED

   性别 (男|女)#REQUIRED

<!ELEMENT %myname; (#PCDATA)>

<!ELEMENT 年龄 (#PCDATA)>

<!ELEMENT 介绍  (#PCDATA)>

<!ENTITY mycopy "我的公司版权">

 

 

学习dtd的目标:一般公司很少让程序员自己写 dtd,要求程序员看的懂dtd,同时可以根据给出的dtd,写出对应的xml

 

一个产品目录

 

<!ENTITY AUTHOR "John Doe">

<!ENTITY COMPANY "JD Power Tools,Inc.">

<!ENTITY EMAIL "jd@jd-tools.com">

 

<!ELEMENTCATALOG (PRODUCT+)>

 

<!ELEMENTPRODUCT

(SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)>

<!ATTLISTPRODUCT

NAMECDATA #IMPLIED

CATEGORY(HandTool|Table|Shop-Professional) "HandTool"

PARTNUMCDATA #IMPLIED

PLANT(Pittsburgh|Milwaukee|Chicago) "Chicago"

INVENTORY(InStock|Backordered|Discontinued) "InStock">

 

<!ELEMENTSPECIFICATIONS (#PCDATA)>

<!ATTLISTSPECIFICATIONS

WEIGHTCDATA #IMPLIED

POWERCDATA #IMPLIED>

 

<!ELEMENTOPTIONS (#PCDATA)>

<!ATTLISTOPTIONS

FINISH(Metal|Polished|Matte) "Matte"

ADAPTER(Included|Optional|NotApplicable) "Included"

CASE(HardShell|Soft|NotApplicable) "HardShell">

 

<!ELEMENTPRICE (#PCDATA)>

<!ATTLISTPRICE

MSRPCDATA #IMPLIED

WHOLESALECDATA #IMPLIED

STREETCDATA #IMPLIED

SHIPPING CDATA #IMPLIED>

 

<!ELEMENT NOTES (#PCDATA)>

xml...

<?xml version="1.0"encoding="utf-8"?>

<!DOCTYPE CATALOG SYSTEM 'product.dtd'>

<CATALOG>

<PRODUCT NAME="康师傅矿泉水" CATEGORY="HandTool"PARTNUM="abc" PLANT="Milwaukee"   INVENTORY="Backordered">

<SPECIFICATIONS WEIGHT="800"POWER="600" >这里是细节</SPECIFICATIONS>

<PRICE>110</PRICE>

</PRODUCT>

</CATALOG>

 

Xml编程

j2ee 技术中,主要是学习 java xml操作,和 js xml操作

 

  Dom是w3c推出的标准;  sax是社区的标准

dom

原理

 

我们讲一个快速入门案例:

                            <?xmlversion="1.0" ?>

<班级>

         <学生>

                   <名字>周星驰</名字>

                   <年龄>23</年龄>

                   <介绍>学习刻苦</介绍>

         </学生>

         <学生>

                   <名字>林青霞</名字>

                    <年龄>32</年龄>

                   <介绍>是一个好学生</介绍>

         </学生>

</班级>

代码:(使用dom 去遍历xml文件和指定获取某个节点)

//具体的查询某个学生的信息(显示第一个学生的所有信息)

    //请考虑如何获取某个元素的属性值,(取出)

    public static void read(Document doc){

      

       NodeListnl=doc.getElementsByTagName("学生");

       //取出第一个学生

       Elementstu=(Element) nl.item(0);

       System.out.println("学生的性别是"+stu.getAttribute("sex"));

       Elementname=(Element) stu.getElementsByTagName("年龄").item(0);

       System.out.println(name.getTextContent());

       //System.out.println("发现"+nl.getLength());

      

    }

   

    //遍历该xml文件

    public static void list(Node node){

       if(node.getNodeType()==node.ELEMENT_NODE){

           System.out.println("名字"+node.getNodeName());

       }

       //取出node的子节点

       NodeListnodeList=node.getChildNodes();

       for(int i=0;i<nodeList.getLength();i++){

           //再去显示

           Noden=nodeList.item(i);

           list(n);

       }

      

    }

        

        

       下面的是使用dom 取添加一个新的元素:

         //添加一个学生到xml文件中

    public static void add(Document doc) throws Exception{

      

       //创建一个新的学生节点

       Element newStu=doc.createElement("学生");

       //添加一个属性值

       newStu.setAttribute("sex","");

       Element newStu_name=doc.createElement("名字");

       newStu_name.setTextContent("小明2");

       Element newStu_age=doc.createElement("年龄");

       newStu_age.setTextContent("34");

       Element newStu_intro=doc.createElement("介绍");

       newStu_intro.setTextContent("这是一个好孩子");

       newStu.appendChild(newStu_name);

       newStu.appendChild(newStu_age);

       newStu.appendChild(newStu_intro);

      

       //把新的学生节点添加到根元素

       doc.getDocumentElement().appendChild(newStu);

      

       //得到TransformerFactory

       TransformerFactorytff=TransformerFactory.newInstance();

       //通过TransformerFactory得到一个转换器

       Transformer tf=tff.newTransformer();

       tf.transform(newDOMSource(doc),new StreamResult("src/classes.xml"));

      

      

    }

 

u           删除某个元素或者是某个属性

 

//删除一个元素(删除小明2学生)

    public static void del(Document doc) throws Exception{

      

       //首先要找到这个学生

       //Nodenode= doc.getElementsByTagName("学生").item(0);

       //node.getParentNode().removeChild(node);

       //删除学生的sex属性

       Element node= (Element)doc.getElementsByTagName("学生").item(0);

       node.removeAttribute("sex");

      

       //更新xml

       //得到TransformerFactory

       TransformerFactory tff=TransformerFactory.newInstance();

       //通过TransformerFactory得到一个转换器

       Transformer tf=tff.newTransformer();

       tf.transform(newDOMSource(doc),new StreamResult("src/classes.xml"));

    }

//更新操作

                   //更新元素(把第一个学生的名改成宋江)

    public static void upd(Document doc) throws Exception{

   

           //找到

           Element node=(Element)doc.getElementsByTagName("学生").item(0);

           Element node_name=(Element)node.getElementsByTagName("名字").item(0);

           node_name.setTextContent("宋江");

           //node_name.setAttribute("sex", arg1)

           //更新xml

           //得到TransformerFactory

           TransformerFactorytff=TransformerFactory.newInstance();

           //通过TransformerFactory得到一个转换器

           Transformer tf=tff.newTransformer();

           tf.transform(new DOMSource(doc),newStreamResult("src/classes.xml"));

    }

 

sax

1.为什么会出现sax技术

因为dom技术,会把整个xml文件加载到内存中,这样如果   xml过大,则可能会出现内存溢出.

2  sax技术可以在不加载全部 xml 文件时,就可以解析xml文档,看一个原理图:

 

3  sax主要用于对xml文件解析(读取),不能去修改,删除,添加元素

4  sax是推机制,把发现的内容告诉程序员(函数),程序员可以自己决定如何处理

 

 

sax技术的案例:     

package com.sax.test;

importjavax.xml.parsers.*;

importorg.xml.sax.Attributes;

importorg.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

public class Sax1 {

    //使用sax技术去解析xml文件.myclasses2.xml

    public static void main(String[] args)throws Exception, SAXException {

       // TODO Auto-generated method stub

       //1.创建SaxParserFactory

       SAXParserFactory spf=SAXParserFactory.newInstance();

       //2.创建SaxParser解析器

       SAXParser saxParser=spf.newSAXParser();

       //3 xml文件和事件处理对象关联

       saxParser.parse("src/myclasses2.xml",new MyDefaultHandler2() );

    }

}

//请思考,如何只显示学生的名字和年龄

class MyDefaultHandler2extends DefaultHandler{

    private boolean isName=false;

    private boolean isAge=false;

    @Override

    public void characters(char[] ch,int start,int length)

           throwsSAXException {

       // TODO Auto-generated method stub

       String con=newString(ch,start,length);

       if(!con.trim().equals("")&&(isName||isAge)){

           System.out.println(con);

       }

       isName=false;

       isAge=false;

       //super.characters(ch,start, length);

    }

    @Override

    public void endDocument() throwsSAXException {

       // TODO Auto-generated method stub

       super.endDocument();

    }

    @Override

    public void endElement(String uri, String localName,String name)

           throwsSAXException {

       // TODO Auto-generated method stub

       super.endElement(uri,localName, name);

    }

    @Override

    public void startDocument() throwsSAXException {

       // TODO Auto-generated method stub

       super.startDocument();

    }

    @Override

    public void startElement(String uri, String localName,String name,

           Attributes attributes) throws SAXException {

       // TODO Auto-generated method stub

       if(name.equals("名字")){

           this.isName=true;

       }else if(name.equals("年龄")){

           this.isAge=true;

       }

    }

}

//定义事件处理类

class MyDefaultHandler1extends DefaultHandler{

    //发现文档开始

    @Override

    public void startDocument() throwsSAXException {

       // TODO Auto-generated method stub

       System.out.println("startDocument()");

       super.startDocument();

    }

    //发现xml文件中的一个元素

    @Override

    public void startElement(String uri, String localName,String name,

           Attributes attributes) throws SAXException {

       // TODO Auto-generated method stub

       System.out.println("元素名称="+name);  

    }

    //发现xml文件中的文本

    @Override

    public void characters(char[] ch,int start,int length)

           throwsSAXException {

       String con=newString(ch,start,length);

       //显示文本内容:

       if(!con.trim().equals("")){

           System.out.println(new String(ch,start,length));

       }

    }

    //发现xml文件中一个元素介绍</xx>

    @Override

    public void endElement(String uri, String localName,String name)

           throwsSAXException {

       // TODO Auto-generated method stub

       super.endElement(uri,localName, name);

    }

    //发现文档结束

    @Override

    public void endDocument() throwsSAXException {

       // TODO Auto-generated method stub

       System.out.println("endDocument()");

       super.endDocument();

    }

}

 

        

 

dom4j

1.       为什么有dom4j

dom 缺点:比较耗费内存

sax缺点: 只能对xml进行读取,但是不能去  修改,添加,删除

dom4j:既可以提高效率,同时也可以进行crud

 

特别说明:因为dom4j不是sun公司的产品,所以我们开发dom4j需要引入jar包

 

快速入门 

如何使用dom4j技术对xml进行(crud)操作

 

l  xpath的必要性

为了我们根据方便的访问的某个节点,我们可以使用xpath技术,当使用xpath后,就可以非常方便的读取到指定节点,xpath往往是结合dom4j一并使用.

说明:如果要使用xpath 则需要引入一个新的包: jaxen-1.1-beta-6.jar



原理图:

 

 

特别说明:

 

//@id

选择所有的id属性


     <AAA>
          <BBB
id = "b1"/>
          <BBB
id = "b2"/>
          <BBB name = "bbb"/>
          <BBB/>
     </AAA>

 

如果我们通过 //@id 取回的节点类型是 Attribue,不是Element

//3.可以使用xpath随心读取

                Liste=document.selectNodes("//@id");//返回多个元素

       System.out.println(((Attribute)e.get(1)).getText());

//注意:xpath是可以任意组合:

<?xmlversion="1.0"encoding="utf-8"?>

<AAA>

          <BBBid= "b1">

          <CCC>

          <KKK>k2</KKK>

          </CCC>

          <CCC>

          <KKK>k1</KKK>

          </CCC>

          </BBB>

          <BBBid= "b2"/>

          <BBBname= "bbb"/>

          <BBB/>

</AAA>

要找到  <KKK>k2</KKK>xpath 应该这/AAA/BBB[1]/CCC[1]/KKK

 

案例:

         package com.dom4jxpath.test;

import java.util.List;

 

import org.dom4j.*;

import org.dom4j.io.*;

 

public class Test1 {

 

    //dom4j 配合 xpath案例

    public static void main(String[] args)throws Exception {

       // TODOAuto-generated method stub

       //1.得到SAXReader解析器

       SAXReadersaxReader =new SAXReader();

       //2.指定去解析哪个文件

       Documentdocument = saxReader.read("src/com/dom4jxpath/test/test.xml");

      

       //3.可以使用xpath随心读取

       Liste=document.selectNodes("/AAA/BBB[1]/CCC[1]/KKK");//返回多个元素 document.selectSingleNode

       System.out.println(((Element)e.get(0)).getText());

       //System.out.println(((Attribute)e.get(1)).getText());

      

      

       //如果我们确定只有一个Node,元素则可以使用selectSingleNode

       //Element e2=(Element)document.selectSingleNode("/AAA/BBB[last()]");

    //System.out.println(e2.getText());

    }

 

}

 

 

 

 

 


0 0