xml

来源:互联网 发布:天泽网络 编辑:程序博客网 时间:2024/05/21 19:29
XML:可扩展标记语言
    标签可以自定义,任何标签都可以
    xml可以显示数据,主要功能是为了存储数据(可模拟数据库)
    是W3C组织发布的技术
    使用1.0的版本,1.1不能实现向下兼容
    应用:1.不同系统之间传输数据
          2.用来表示生活中有关系的数据
          3.经常用在配置文件中
             --比如现在连接数据库,肯定知道数据库的用户名和密码,数据名称
               如果修改数据库的信息,不需要修改源代码,只要修改配置文件就可以了
     XML语法:
       1.xml文档声明
         --创建文件.xml
         --如果写xml,第一部必须要有一个文档声明:
           <?xml version="1.0" encoding="utf-8">
           文档生命必须写在第一行第一列,不应该有空格
           属性:-version:xml版本
                 -encoding:xml的编码
                 -standalone:是否需要依赖其他文件yes/no(用的少)
            xml中文乱码解决:设置保存时候的编码和打开时候的编码一致
       2.定义元素(标签)
          --一个xml文档必须有且只有一个根标签
          --在xml中,空格和换行都作为原始内容被处理
          <网址>www.itcast.cn</网址>   
 <网址>
      www.itcast.cn
 </网址>  
以上两个是不同的。
          XML标签规范:
             --xml区分大小写
             --不能以数字,下划线开头
             --不能包含空格
             --不能以xml或Xml或XML开头
             --名称中间不能包含冒号
            xml的标签可以是中文
       3.定义属性
           --1.一个标签上可以有多个属性
             2.属性名称不能相同
             3.属性名称和属性值之间使用=,属性值要用引号(可单可双)
             4、命名规范和元素名称的规范一致
       4.注释:
            <!-- xml的注释 -->
           注释也不能放到第一行,第一行第一列必须放文档声明
       5.xml中的特殊字符:
         <:&lt;
         >:&gt;
     
       6.CDATA区
          可以解决多个字符都需要转义的操作,把需要转义的内容放在CDATA区里面,就不需要转义了
          写法:<![CDATA[内容]]>
          <![CDATA[<b> if(a < b && b < c  &&  d>f){}</b>]]>
       7.PI指令(处理指令:Processing Instruction):
         用来指挥软件如何解析XML文档(设置样式)。
         语法:必须以<?开头,以?>结束
         常用处理指令:<?xml version="1.0" encoding="utf-8"?>
         xml-stylesheet指令:指示xml文档所使用的css样式xsl
          <?xml-stylesheet type="text/css" href="some.css">
            注:对中文命名的标签不起作用

XML语法规则总结:
    1.所有XML标签对大小写敏感。
2.所有XML标签都必须有关闭标签。
3.XML必须正确的嵌套顺序。
4.XML必须有根元素。
5.XML的属性值须加引号
6.特殊字符必须转义--CDATA
7.XML中的空格、回车换行会解析时被保留
 
XML约束:
 技术:dtd约束   和   schema约束
 1.dtd快速入门:
     创建一个文件  后缀名.dtd
 步骤:
     1.看xml中有多少个元素:有几个元素,就在dtd文件中写几个
2.判断元素是简单元素还是复杂元素
  注意:元素名称后面一定要有空格
 --简单元素:没有子元素的元素
   <!ELEMENT 元素名称 (#PCDATA)>
 --复杂元素:有子元素的元素
      <!ELEMENT 元素名称 (子元素)>
 3.需要在xml文件中引入dtd文件
   <!DOCTYPE 根元素名称 SYSTEM "dtd文件路径">
  打开xml文件使用浏览器打开的,浏览器只负责校验xml的语法,不负责校验xml约束。
  如果想要校验xml的约束,需要使用工具(eclipse)
   在eclipse里面创建xml文件,dtd文件

 dtd的三种引入方式:
     1.外部引入:<!DOCTYPE 根元素名称 SYSTEM "dtd文件路径">
   <!DOCTYPE person SYSTEM "NewFile.dtd">
 2.使用内部的dtd文件
   <!DOCTYPE person [
<!ELEMENT person (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
  ]>
 3.使用外部的dtd文件(网络上的dtd文件):
   <!DOCTYPE 根元素 PUBLIC "dtd名称" "dtd文档的URL">
后面学struts2框架使用配置文件 使用外部的dtd文件
 
使用dtd定义元素:
   语法:<!ELEMENT 元素名 约束>
简单元素:没有子元素的元素
    1.<!ELEMENT name (#PCDATA)>
 (#PCDATA):表示约束name是字符串类型
2.<!ELEMENT sex EMPTY>
              EMPTY:元素为空(没有内容)
             3.<!ELEMENT school ANY>
              ANY:任意
        复杂元素:
             <!ELEMENT person (name ,age ,sex)>
                --子元素只出现一次
              *<!ELEMENT 元素名称 (子元素)>
              *表示子元素出现的次数:
                   + :表示一次或多次
                   ? :表示0次或1次
                   * :表示出现0次或多次(无论多少次都可以)
<!ELEMENT person (name+ ,age? ,sex*)>
 --表示name可以出现一次或多次
 --表示age可以出现0次或1次
 --表示sex可以出现任意次
               *子元素直接使用逗号隔开:表示元素出现的顺序
               *子元素使用|隔开:表示只能出现其中的任意一个  

       使用dtd定义属性:
           语法:<!ATTLIST 元素名称
             属性名称  属性类型 属性的约束
     >  
 <!ATTLIST birthday 
                     ID CDATA #REQUIRED
                  >
  <birthday ID="birth"></birthday>
属性值类型:CDATA:表示属性的取值为普通的文本字符串
            ENUMERATED(dtd没有此关键字):表示枚举,只能枚举列表中人选其一。用一个括号括起来
如(a|b|c)只能取其中的一个;红绿灯效果
ID:表示属性的取值不能重复,属性的值只能由字母,下划线开始,不能出现空白字符
属性约束设置说明:
      #REQUIRED:表示此属性必须出现
  #IMPLIED:表示该属性可有可无
  #FIXED:表示属性的取值为一个固定值,语法:#FIXED "固定值"
  直接值:不写,使用直接值;写了就是用设置的值
   定义引用实体:
   概念:在dtd中定义,在xml中使用
语法:<!ENTITY 实体名称 "实体内容">
引用方式(注意是在xml中使用):&实体名称
     如:dtd中定义:
     <!ENTITY copyright "传智播客版权所有">
 xml中引用:
   &copyright;

注意:定义实体需要写在内部dtd里面,如果写在外部dtd里面,在某些浏览器下内容得不到。

 1.dtd:  

<!ELEMENT person (name,age)><!ELEMENT name (#PCDATA)><!ELEMENT age (#PCDATA)>
demo.xml:
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE person SYSTEM "1.dtd"><person>    <name>张三</name><age>23</age></person>


XML的解析简介:(写到java代码)
    xml是标记型文档 
       js解析标记型文档:根据html的层级结构,在内存中分配一个树形结构,把html标签,属性和文本都封装成对象。
                  document对象,element对象,属性对象,文本对象,Node对象
     xml的解析方式(技术):dom 和 sax【经常被问到】
 
dom和sax解析的区别:
使用dom解析:根据xml的层级结构在内存中非配一个树形结构把xml的标签,属性和文本封装成对象。
 优点:很方便的实现增删改操作
 缺点:如果文件过大,造成内存溢出
使用sax解析:采用事件驱动,边读边解析(从上到上,一行一行的解析,解析到某一个对象,把对象名称返回。)
优点:不会造成内存溢出,方便实现查询
                       缺点:不能实现增删改操作
 
         想要解析xml,首先需要解析器
   不同的公司和组织提供了针对dom和sax方式的解析器,通过api提供
解析器(是解析器,而不是解析技术):
 sun公司:jaxp
 dom4j: dom4j(开发中使用最多)
 jdom: jdom
 
jaxp:是javase的一部分
jaxp解析器是在javax.xml.parsers包中,定义了几个工厂类
dom:DocumentBuilder  解析器类
--抽象类,不能new,此类的实例可以通过DocumentBuilderFactory.new DocuemntBuilder()获取 一个方法,可以解析xml parse("xml路径") 返回是Document整个文档
返回的Document是一个接口,父节点是Node ,如果在Document里面找不到想要的方法,到Node里面找在document里面方法:
NodeList getElementsByTagName(String tagName)//这个方法可以得到标签,返回集合NodeList
Element getElementById(String elementId) //返回具有带给定值的 ID 属性的 Element。
Element createElement(String tagName)//创建标签
Text createTextNode(String data) /创建文本
Node appendChild(Node newChild) //把文本添加到标签下面
Node removeChild(Node oldChild) //使用父节点删除节点
Node getParentNode()//获取父节点

Node getFirstChild()//此节点的第一个节点
Node getLastChild()//此节点的最后一个节点
Node cloneNode(Node deep)//返回此节点的副本,即允当节点的一般复制构造方法
Node replaceChild(Node newChild, Node oldChild)// 将子节点列表中的子节点 oldChild 替换为 newChild,并返回 oldChild 节点。

NodeList list
 --int getLength():得到集合长度
 --Node item(int index):根据下标取到具体的值
 遍历:
for(int i = 0 ; i < list.getLength() ; i++){
 list.item(i);
 }
String getTextContext()// 得到标签里的内容
DocumentBuilderFactory   解析器工厂
   --抽象类,不能new,通过newInstance()获取DocumentBuilderFactory的实例
sax:SAXParser 解析器类 
SAXParserFactory  解析器工厂

        使用jaxp实现查询操作的步骤:
          1.创建解析器工厂:DocuemnDocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance()
          2.根据解析器工厂创建解析器 DocuemntBuilder builder = builderFactory.newDocuemntBuilder()
          3.解析xml返回document  Docuemnt document = builder.parse("src/person.xml");
          4.得到所有要查询的元素 NodeList list = document.getElementsByTagName("name");
          5.返回集合,遍历集合,得到每一个要查询的元素的内容 

     练习:查询person.xml中所有name元素的值
 
import javax.w3c.*;
     public class Test{
  public static void main(String[] args) throw Exception{
  /**
   *1.创建解析器工厂
      *2.根据解析器工厂创建解析器
      *3.解析xml返回document
      *4.得到所有的name元素
      *5.返回集合,遍历集合,得到每一个name元素
/
//1.创建解析器工厂
  DocumentBuilderFactory buildFactory = DocumentBuilderFactory.newInstance();
               //2.根据解析器工厂创建解析器
  DocuemntBuilder builder = buildFactory.newDocumentBuilder();
     //3.解析xml返回document
  Docuemnt document = builder.parse("src/person.xml");
  NodeList list = document.getElementsByTagName("name");
  //遍历集合
  for(int i = 0 ; i < list.getLength() ; i++){
     Node name = list.item(i);
 //得到name元素的值
 String str = name.getTextContext();
 System.out.println(str);
  }
  }
} 
           
使用jaxp添加元素:
*1.创建解析工厂
* 2.创建解析器
* 3.解析xml返回Document对象
* 4.得到所有的p1标签,用item(int index)得到指定下标的元素
* 5.创建sex标签  createElement()
* 6.创建文本标签 createTextNode()
* 7.把文本添加到sex下面
* 8.把sex添加到p1下面
* 9.回写xml

使用jaxp修改节点:
     * 1.创建解析工厂
* 2.创建解析器
* 3.解析xml返回document对象
* 4.得到sex元素
* 5.修改sex里面的值  setTextContent()
* 6.回写xml
    
    使用jaxp删除节点:
* 1.创建解析工厂
* 2.创建解析器
* 3.解析xml返回document对象
* 4.得到sex元素
* 5.得到sex的父节点 父节点删除节点:removeChild()
* 6.删除sex
* 7.回写xml  
    
使用jaxp遍历节点:
* 1.创建解析工厂
* 2.创建解析器
* 3.解析xml返回document对象

* ===使用递归得到所有节点
* 4.得到根节点
* 5.得到根节点的子节点

* 6.得到根节点的子节点的子节点

 

<?xml version="1.0" encoding="utf-8" standalone="no"?><person>    <p1>     <name>zhangSan</name> <age>20</age>     </p1><p1>     <name>liSi</name> <age>22</age></p1></person>

/**使用jaxp实现xml的解析 * @ProjectName:xml * @ClassName:TestJaxp * @author xkf * @email 2547951466@qq.com * @date 2015年9月18日 * @Description:无 */public class TestJaxp {/**查询person.xml中所有name元素的值 * @Title:selectAll * @Description: * @throws Exception * @return void */public static void selectAll() throws Exception{//1.创建解析器工厂DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();//2.创建解析器DocumentBuilder builder = builderFactory.newDocumentBuilder();//3.解析xml返回DocumentDocument docuemnt = builder.parse("src/person.xml");//4.得到所有的name属性NodeList list = docuemnt.getElementsByTagName("name");//5.遍历集合for (int i = 0; i < list.getLength(); i++) {Node name = list.item(i);//得到name元素的值String strName = name.getTextContent();System.out.println(strName);}}/**查询xml中的第一个name元素的值:list.item(指定的下标); * @Title:selectSingnal * @Description: * @return void */public static void selectSingnal() throws Exception{//1.创建解析工厂DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();//2.创建解析器DocumentBuilder builder = builderFactory.newDocumentBuilder();//3.解析xml返回DocumentDocument document = builder.parse("src/person.xml");//4.得到所有的name元素NodeList list = document.getElementsByTagName("name");//使用下标得到第一个name元素Node name = list.item(0);//得到name元素的值String strName = name.getTextContent();System.out.println(strName);}/**使用jaxp添加一个节点:sex * 1.创建解析工厂 * 2.创建解析器 * 3.解析xml返回Document对象 * 4.得到所有的p1标签,用item(int index)得到指定下标的元素 * 5.创建sex标签  createElement() * 6.创建文本标签 createTextNode() * 7.把文本添加到sex下面 * 8.把sex添加到p1下面 * 9.回写xml * @Title:addElement * @Description: * @return void */public static void addElement() throws Exception{//1.创建解析器工厂DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();//2.创建解析器DocumentBuilder builder = builderFactory.newDocumentBuilder();//3.解析xml返回Document对象Document document = builder.parse("src/person.xml");//4.得到第一个p1标签:得到所有的p1,使用item()下标得到NodeList list = document.getElementsByTagName("p1");Node p1 = list.item(0);//5.创建sex标签createElement()Element sex = document.createElement("sex");//6.创建文本createTextNode()Text text = document.createTextNode("男");//7.把文本添加到sex下面sex.appendChild(text);//8.把sex添加到p1下面p1.appendChild(sex);//9.回写xml,不回写的话就不会在xml中显示刚刚添加的节点//这个回写操作不需要掌握,用的时候直接来复制即可TransformerFactory transformerFactory = TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();transformer.transform(new DOMSource(document), new StreamResult("src/person.xml"));}/**修改p1里面的sex为女:setTextContent() * 1.创建解析工厂 * 2.创建解析器 * 3.解析xml返回document对象 * 4.得到sex元素 * 5.修改sex里面的值  setTextContent() * 6.回写xml * @Title:modifyElement * @Description: * @return void */public static void modifyElement() throws Exception{DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = builderFactory.newDocumentBuilder();Document document = builder.parse("src/person.xml");Node sex = document.getElementsByTagName("sex").item(0);sex.setTextContent("女");TransformerFactory transformerFactory = TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();transformer.transform(new DOMSource(document), new StreamResult("src/person.xml"));}/**使用jaxp删除节点 * 1.创建解析工厂 * 2.创建解析器 * 3.解析xml返回document对象 * 4.得到sex元素 * 5.得到sex的父节点 * 6.删除sex * 7.回写xml * @Title:removeElement * @Description: * @return void */public static void removeElement() throws Exception{DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = builderFactory.newDocumentBuilder();Document document = builder.parse("src/person.xml");Node sex = document.getElementsByTagName("sex").item(0);Node p1 = sex.getParentNode();p1.removeChild(sex);TransformerFactory transformerFactory = TransformerFactory.newInstance();Transformer transformer = transformerFactory.newTransformer();transformer.transform(new DOMSource(document), new StreamResult("src/person.xml"));}/**使用jaxp遍历节点:打印所有元素的名称 * 1.创建解析工厂 * 2.创建解析器 * 3.解析xml返回document对象 *  * ===使用递归得到所有节点 * 4.得到根节点 * 5.得到根节点的子节点 * 6.得到根节点的子节点的子节点 * @Title:forEachElement * @Description: * @return void */public static void forEachElement() throws Exception{DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = builderFactory.newDocumentBuilder();Document document = builder.parse("src/person.xml");//用一个方法实现递归遍历所有节点listNodes(document);}private static void listNodes(Node node) {if(node.getNodeType() == node.ELEMENT_NODE){System.out.println("属性名:" + node.getNodeName());}//得到一层子节点NodeList list = node.getChildNodes();//遍历listfor (int i = 0; i < list.getLength(); i++) {//得到每一个节点Node node1 = list.item(i);//递归调用listNodes(node1);}}public static void main(String[] args) {try {//selectAll();//selectSingnal();//addElement();//modifyElement();//removeElement();forEachElement();} catch (Exception e) {e.printStackTrace();}}}

0 0
原创粉丝点击