XML详解与相关解析

 XML ( Extensible Markup Language ( 可拓展标记语言 ))

    是SGML(标准通用标记语言)即允许用户对自己的标记语言进行定义的源语言,

    是Internet环境中跨平台的,依赖于内容技术,是处理结构化文档信息的有力工具。

    是一种简单的数据存储语言,它使用一系列简单的标记描述数据。

    是W3C组织发布的(包括HTML, CSS)

    简称:在XML语音中,它允许用户自定义标签,一个标签用于描述一段数据; 一个标签可以分为开始标签和结束标签,在开始和结束标签之间,又可以使用其他标签描述其他数据, 以此来实现数据关系的描述。

    XML技术除了用于保存有关的数据之外,它还经常用作软件配置文件,以描述程序模块之间的关系。

    在一个软件系统中,为了提高系统的灵活性,它所启动的模块通常由其配置文件决定。

例如:一个软件在启动时,它需要启动A,B两个模块,在这两个模块启动时,又分别需要启动A1,A2和B1,B2的支持,为了准确描述这种关系,XML最为合适。

    历史:刚开始W3C推出XML是为了取代HTML,中间还使用Xhtml过度,但是因为学习成本较高,没有实现取代,后面才作为其他作用。

    标记语言:由一些格式代码(codes) 或控制标记 (tags)组成。标记决定信息的显示格式或数据的意义,但这些标记不能单独存在,只用于修饰它所包括的信息。

详细语法:

一个Xml文件分为以下几个内容

①文档声明(没有声明的文档称为格式不良好文档,所以必须要有,且要求放到第一句)

    最简单的声明语法:

    <?xml version="1.0"?>

    用encoding属性说明文档的字符编码:

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

    用standalone属性说明文档是否独立:(是否依赖于其他文档)

    <?xml version="1.0" encoding="GB2312" standalone="yes" ?>

②元素(element)

    1,XML文件中出现的标签,一个标签分为开始标签和结束标签,一个

         标签有两种书写形式:包含标签体<a>abcd</a>, 不含标签体<a/>

    2,一个标签中可以嵌套若干子标签,但所有标签必须合理的嵌套,绝不允许相互嵌套;

        例如 A中有B,在A结束标签前,B标签必须已经在A内部结束;

    3,格式良好的XML文档必须有且仅有一个根标签,其他表示都是这个根标签的子孙标签。

    对于XML中出现的所有空格和换行,XML解析程序都会当作标签内容进行处理。

        例如:下面两段内容的医院是不一样的。

                第一段:<国家>China</国家> 

                第二段:<国家>

                                    China

                              </国家> 

       由于在XML中,空格和换行都作为原始内容被处理,所以,在编写XML文件时,

使用换行和缩进等方式让原文件中的内容清晰可读的”良好“书写习惯可能被迫改变。

    4,一个XML元素可以包含字母,数字,以及其他一下可见字符,但必须遵守下面的一些规范:

    区分大小写;

    不能以数字或”_“ (下划线)开头;

    不能以xml(或XML,Xml等)开头;

    不能包含空格。

    名称中间不能包含冒号(:)

③属性

    一个标签可以有多个属性,每个属性都有它自己的名称和取值,例如:

    <input name="text">

    属性值一定要用双引号(”)或单引号(')引起来

    定义属性必须准信与标签相同的命名规范

    在XML技术中,标签属性所代表的信息,也可以被改成用子元素的形式来描述(属性封装或子元素封装)

    例如:

    <input>

        <name>text</name>

    </input>

④注释 

    格式: <!--注释-->

    XMl声明之前不能有注释,注释不能嵌套

CDATA区,特殊字符

    在编写XML文件时,有些内容可能不想让解析引擎执行解析执行,而是当中元素内容处理。

    这种情况可以吧这些内容放到CDATA区里,对于CDATA区域内的内容,

    XML解析程序不会处理,而是执行原封不动的输出。例如:

    语法:<![CDATA[内容]]>

    <![CDATA[

        <itcast>

                <br/>

        </itcast>

    ]]>

特殊字符

&    &amp

>    &gt

<    &lt

"    &quot

'    &apos

处理指令(processing instruction)

简称PI( processing instruction ) 。处理指令用来之后解析引擎如何解析XML文档内容。

例如在XML文档中可以使用xml-stylesheet指令,通知XML解析引擎,应用css文件显示xml文档内容。

<?xml-stylesheet type="text/css" href="1.css"?>
处理指令必须以“<?”作为开头,以“?>”作为结尾

XML声明语句就是最常见的意志处理指令。

XMl约束概述:

在XML技术里,可以编写一个文档来约束一个XML文档的书写规范,这称之为XML约束。

常用的约束技术:XML DTD ; XML Schame

DTD(Document Type Dedinition),全称为文档类型定义。

例如:

文件清单:book.xml

<?xml version="1.0"?>

<!DOCTYPE 书架 SYSTEM"book.dtd">

<书架>

    <书>

         <书名>java</书名>

          <作者>Bob</作者>

          <价格>10.00元</价格>

    </书>

</书架>

文件清单:book.dtd

<!ELEMENT 书架(书+)>   +代表可以放一本或多本

<!ELEMENT 书(书名,作者,售价)> 指明仅能放书名,作者和售价

<!ELEMENT 书名(#PCDATA)>  parse character data 可解析的字符数据,即字符串

<!ELEMENT 作者(#PCDATA)>

<!ELEMENT 售价(#PCDATA)>

DTD文件应用使用UTF-8或Unicode

 

与html区别

①xml允许自定义标签名,html不支持 

②xml是存储数据,html是显示数据  

 XML的结构解析:1,节点,2,元素,3,属性和属性值

DOM解析XML文件

“文档对象模型”方式,解析完XML将生产一个树状结构的对象。 

实例:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

DocumentBuilder builder = dbf . newDocumentBuilder ();

Document doc = builder . parse ( xmlPath ) ; 

得到doc后获取节点集合

NodeList  list = doc . getElementsByTagName ( "message" );

获取每一个节点内的信息;

Node node = list . item( 0 );

String msg = note . getFirstChild() . getNodeValue();

基本DOM对象

①Domcument

        代表整个XML文档,所有其他的Node,都以一定顺序包含在Document对象内,排列成一个树形结构

        createAttribute ( String )

用给定的属性名创建一个Attr对象,并可在其后使用setAttributeNode方法来放置在某一个Element对象上面。

        createElement ( String )

用给定的标签名创建一个Element 对象,代码XML 文档中的一个标签,然后就可以在这个Element对象上添加属性或者进行其他的操作。

        crateTextNode ( String ) 

用给定的字符串创建一个Text对象, Text对象代码了标签或者属性中所包含的纯文本字符串。如果在一个标签内没有其他的标签,那么标签内的文本所代码的Text对象是这个Element对象的唯一子对象。

        getElementByTagName ( String ) 

返回一个NodeList对象,包含所有给定标签名字的标签。

        getDocumentElement () 

返回一个代表这个DOM树的根节点的Element对象,即文档根元素对象

        

②Node

        代表文档中的一个抽象的节点,实际很少会真正用到Node对象,而是用Element , Attr, Text 等Node对象的子类对象操作文档。Node对象为这些对象提供一个抽象的,公共的根。

        appendChild ( org.w3c.dom.Node ) 

为这个节点添加一个子节点,并放在所有子节点的最后,如果子节点已存在,则先把它删除再填加进去

        insertBefore ( org.w3c.dom.Node new , org.w3c.dom.Node ref )

在给定的一个子对象前面再插入一个子对象。    

        getFirstChild () 

如果节点存在子节点,返回第一个子节点,(getLastChild()返回最后一个子节点)

        getNodeName()     

        hasChildNodes() 

        hasArrtributes() 

判断这个节点是否存在属性

        getOwnerDocument()

返回节点所处的Document对象

③NodeList

        包含一个或多个Node的列表,可简单视为一个Node数组

        item( int ) 返回指定位置的Node对象

④Element

        代表XML文档中的标签元素,继承Node,也是Node最主要的子对象

        在标签中科院包含属性,因而Element对象中有存取其属性的方法,

        getElementsByTagName ( String ) 

返回一个NodeList对象,包含了标签中旗下的子孙节点中具有给定签名字的标签。

        getTagName()

        getAttribute ( String ) 返回标签中给定的属性名称的属性值

        getAttributeNode ( String ) 返回一个代码给定属性名称的Attr对象

⑤Attr

        代表某标签中的属性,继承与Node,Attr实际包含在Element中,所以不能被视为Element的子对象

        在DOM中Attr并不是DOM树的一部分,所以Node中的getparentNode(),getpreviousSibling()和getnextSibling() 返回都是null

XML详解与相关解析_第1张图片

SAX解析XML文件(Simple API for XML)

与DOM比较而言sax是一种轻量型的方法,

DOM是文档驱动的,在处理DOM时候,需要读取整个XML文档,然后在内存中创建DOM树,生成DOM树上的每个Node对象,当文档大起来时候是相当费劲的。

SAX是事件驱动的,不需读入整个文档,读文档的过程就是解析的过程,

它解析速度快,占内存少,这种解析器比较适合android等移动设备。


优点:流的方式处理,遇到标签时不会记录下当前所遇到的标签(在startElement()中,知道的仅是当前标签的名字和属性,至于标签的嵌套结构,上层标签名,是否有子元素与其他结构相关的信息,都是不知道的)。

在XMLReader , SAXParser 接收XML文档,在读入XML文档的过程中就进行解析,解析前需要向XMLReader/SAXParser注册一个ContentHandler监听,一般使用DefaultHander的子类处理XML文件

        void startDocument()  

在遇到文档开头时候调用,一般做预处理工作

        void startElement ( String namespaseURI , String localName, String  qName,    Attributes atts )

读到开始标签时触发,namespaceURI是命名空间,localName是不带命名空间的标签名,qName是带命名空间的标签名,通过stts得到所有的属性名和相应的值

        void characters( Char[] ch,int start,int lenght )

用于处理节点中读到的内容,第一个参数是文件的字符串内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用 new String ( ch , start , lenght )就可以获取内容

        endEliment

和上面的startElement()方法对应,遇到结束标签的时候,调用这个方法。

        endDocument

和上面的sartDocument()方法相对应,当问到结束时,调用这个方法,可以在其中做一些善后的工作。

实例:

解析如下XML文件:

XML详解与相关解析_第2张图片

①MyHandler继承DefaultHander

②重写    startDocument(){}

              startElement(){}

              characters(){}

              endElement(){}

详:

private HashMap<String,String> map=null;//存储单个解析的完整对象

private List<HashMap<String,String>>list=null;//存储所有的解析对象

private String currentTag=null;//正在解析的元素的标签

private String currentValue=null;//解析当前元素的值

private String nodeName=null;//解析当前的节点名称

public My Handler( String nodeName ){

    this.nodeName=nodeName;

}

public List<HashMap<String,String>>getList(){ return list}

重写 startDocument(){

    //当读到第一个开始标签的时候触发   

    list=new ArrayList<HashMap<String,String>>();

}

重写 startElelent(){

    //当遇到文档开头的时候,调用这个方法

    if(qName.equse(nodeName){

        map=new HashMap<String,String>();

    }

    if(attributes != null && map!=null){

        for(int i = 0; i<attributes ; i++){

            map.put(attributes.getQName(i),attributes.getValue(i));

        } 

    }

    curentTag=qName;

}

重写 characters(){

//处理XML文件读到的内容

    if(curentTag!=null&&map!=null){

        curentValue=new String(ch,start,leng);//声明字符串装置节点对应的值

        if(currentValue!=null&&currentValue.trim().equals("")

                &&!curentValue.trim().equals("\n")){

            map.put(currentTag,currentValue);

        }

    }

currentTag=null;//把当前节点的对应的值和标签设置为空

currentValue=null;

}

重写endElement(){

//遇到结束标记的时候,会调用这个方法//准备解析下一个节点

    if(qName.equalse(nodeName)){

    list.add(map);

    map=null;

    } 

}

XML详解与相关解析_第3张图片

使用pull来解析XML文件

pull解析器是一个开源的java项目,可用于android 也可用于其他的JavaEE项目中,

Pull已经默认集成到android类库中,

它类似于SAX方式,程序以“拉取”的方式对xml进行解析。

pull运行方式与SAX解析相似,提供了一个用户解析XML的接口:Xmlpullparser,

提供了和SAX类似的事件:

开始和结束的元素事件,使用parser,nest() 进入下一个元素并触发事件,和SAX不同的是,Pull解析器参数的事件是一个数字(使用其中的常量来比较),而非方法,因此可以swich 对感兴趣的事件进行处理,当元素开始解析时,调用parser.nextText()方法可以获取下一个Next类型节点的值。

使用pull解析器,可以根据需要只读取XML的部分内容,需要的数据被读取到的时候不再往下读。

文档声明 0   START_DOCUMENT;

文档结束 1  END_DOCUMENT;

开始标签 2   START_TAG

结束标签 3  END_TAG

读取文本 4   TEXT

三种解析方式的比较:

DUM 

解析方式                   将一个xml文件先按树的方式进行存储然后根据相应的方法解析加载整个XML文件

随机读取解析            支持

可生成xml文件         不可以

SAX 

解析方式                   从XML文件头开始解析,无需全部加载 , 以触发事件,调用相应的方法解析

随机读取解析            不支持 

可生成xml文件         不可以  

PULL

解析方式                   以触发事件,执行相应的事件常量来进行解析,从XML文件头开始解析

随机读取解析            不支持

可生成xml文件         可以

对应实例的类

SaxService{

    public SaxService(){

    }

    public static List<List<HashMap<String,String>>>readXML(

        InputStream  inputStream, String nodeName){

            List<HashMap<String,String>>list =null;

            try{

                //创建一个解析XML的工厂对象

                SAXParserFactory spf =SAXParserFactory.newInstans();

                SAXParser sparser = spf.newSAParser();

                MyHandler hander =new MyHandler(nodeName);

                parser.parse(inputStream,handler);

                inputStream.close();

                return handler.getList();

            }catch(){}

            return null;

    } 

}

对应的网络上下载的XML文件

public class HttpUtils{

        public HttpUtilsP(){}

        public static InputStream getXML(String path){

                InputStream inputStream =null;

                try{

                        URL   ur =new URL( path );

                        if(url!=null){

                            HttpURLConnection connection = (HttpURLConnection)

                                        .openConnection();

                            connection.setConnectionTimeOut(3000);

                            connection.setDoInput(true);

                            connection.setRequesMethod("GET");  

                            int code =connection.getResposeCode();

                            if(code==200){

                                   inputStream = connection.getInputStream();

                            }

                    }    

                }

         return null; 

}  

}

测试类

void main(){

    String paht ="http://..."

    InputStream is =HttpUtils.getXML(path);

    try{

        list<HashMap<String,String>> list = SaxService.readXML(is,"person");

        for( HashMap<String,String>map : list ){

            syso(map.toString());

        }

    }catch(){}

}


你可能感兴趣的:(xml)