黑马程序员_各种方法解析XML文件学习

本文详细介绍了XML文件的解析方法,包括使用DTD、Schema进行验证,DOM、SAX和JDOM的解析方式,并提供了相应的代码示例。通过对XML文件的解析,我们可以有效地读取和处理XML数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

-----------------------------android培训java培训期待与您交流!----详细请查看:http://edu.youkuaiyun.com/heima---------------


DTD解析XML文件:

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

<!DOCTYPE 学生名册SYSTEM "dtd_4.dtd">

<学生名册>

       <学生学号="t1">

              <姓名>张三</姓名>

              <性别>男</性别>

              <年龄>20</年龄>

       </学生>

</学生名册>

 

**对应的DTD文件:

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

<!ELEMENT学生名册 (学生+)>

<!ELEMENT学生 (姓名, 性别, 年龄)>

<!ELEMENT姓名 (#PCDATA)>

<!ELEMENT性别 (#PCDATA)>

<!ELEMENT年龄 (#PCDATA)>

<!ATTLIST学生 学号 ID #REQUIRED>

 

Schema解析XML文件

xsd 文件开头:

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

<xs:schemaxmlns:xs="http://www.w3.org/2001/XMLSchema"elementFormDefault="qualified"attributeFormDefault="unqualified">

 

对应的xml文件开头:

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

〈根元素xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="XXXX.xsd" >

 

 

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

<学生名册xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="student.xsd" >

       <学生学号="1">

              <姓名>张三</姓名>

              <性别>男</性别>

              <年龄>20</年龄>

       </学生>

</学生名册>

 

**对应的Schema文件

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

<xs:schemaxmlns:xs="http://www.w3.org/2001/XMLSchema"elementFormDefault="qualified"attributeFormDefault="unqualified">

        <xs:element name="学生名册">

        <xs:complexType>

                      <xs:sequence minOccurs="0"maxOccurs="unbounded">

                      <xs:element name="学生">

                             <xs:complexType>

                                           <xs:sequence>

                                           <xs:elementname="姓名" type="xs:string"/>

                                                 <xs:elementname="性别">

                                                  <xs:simpleType>

                                                               <xs:restrictionbase="xs:string">

                                                              

                                                                      <xs:enumerationvalue="男"/>

                                                                      <xs:enumerationvalue="女"/>

                                                             </xs:restriction>

                                                        </xs:simpleType>

                                                                                   

                                                 </xs:element>

                                         

                                                 <xs:elementname="年龄">

                                                

                                                        <xs:simpleType>

                                                              

                                                               <xs:restrictionbase="xs:integer">

                                                                <xs:minInclusivevalue="1" />

                                                                      <xs:maxInclusivevalue="150"/>

                                                                </xs:restriction>

                                                        </xs:simpleType>

                                                  </xs:element>

                                           </xs:sequence>

                                           <xs:attributename="学号" type="xs:integer" />

                                    </xs:complexType>

                           

                            </xs:element>

                    

                     </xs:sequence>

               </xs:complexType>

        </xs:element>

 </xs:schema>

 

DOM解析XML

<?xmlversion="1.0"?>

<PEOPLE>

       <PERSON PERSONID="E01">

              <NAME>TonyBlair</NAME>

              <ADDRESS>10 Downing Street,London, UK</ADDRESS>

              <TEL>(061) 98765</TEL>

              <FAX>(061) 98765</FAX>

              <EMAIL>blair@everywhere.com</EMAIL>

       </PERSON>

</PEOPLE>

 

用DOM解析上面XML文件

 

publicclass DomTest1

{

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

       {

              // step 1: 获得dom解析器工厂(工作的作用是用于创建具体的解析器)

              DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();

             

              // step 2:获得具体的dom解析器

              DocumentBuilder db =dbf.newDocumentBuilder();

             

              // step3: 解析一个xml文档,获得Document对象(根结点)

              Document document = db.parse(newFile("candidate.xml"));

             

              NodeList list =document.getElementsByTagName("PERSON");

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

              {

                     Element element =(Element)list.item(i);

Stringcontent=

       element.getElementsByTagName("NAME").item(0).getFirstChild().getNodeValue();

/*如果是item(0).getNodeValue()f返回的是null;因为<NAME>里的字段业是一个Node*/

System.out.println("name:"+ content);

             /* Lession_3

NodeList list = document.getChildNodes();

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

              {

                     Node n = list.item(i);

                    

                     System.out.println(n.getNodeType() + " :" + n.getNodeValue());

              }

/*得到的结果中Element和文本的nodeName nodeValue的值是:

Interface

nodeName

nodeValue

attributes

Document

"#document"

null

null

Element

same as Element.tagName

null

NamedNodeMap

Text

"#text"

same as CharacterData.data, the content of the text node

null

*/

开始解析属性:

NodeListnodeList = document.getElementsByTagName("学生");

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

              {

                     NamedNodeMap nnm =nodeList.item(i).getAttributes();//属性的Map集合

                    

                     String attrName =nnm.item(0).getNodeName();//获取属性名字nnm.item(0)返回的是 Attr 类型的值。

                     String attrValue =nnm.item(0).getNodeValue();//获取属性的值

}

 

综合:写出一个程序解析任意一个XML文档:采用递归的方法

publicclass DomTest3

{

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

       {

              DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();

              DocumentBuilder db =dbf.newDocumentBuilder();

             

              Document doc = db.parse(newFile("student.xml"));

              //获得根元素结点

              Element root =doc.getDocumentElement();

               parseElement(root);

       }

      

       private static void parseElement(Elementelement)

       {

              String tagName =element.getNodeName();

             

              NodeList children =element.getChildNodes();

              System.out.print("<"+ tagName);

             

              //element元素的所有属性所构成的NamedNodeMap对象,需要对其进行判断

              NamedNodeMap map =element.getAttributes();

             

              //如果该元素存在属性

              if(null != map)

              {

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

                     {

                            //获得该元素的每一个属性

                            Attr attr = (Attr)map.item(i);

                           

                            String attrName =attr.getName();

                            String attrValue =attr.getValue();

                            System.out.print("" + attrName + "=\"" + attrValue + "\"");

                     }

              }

             

              System.out.print(">");

             

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

              {

                     Node node =children.item(i);

                     //获得结点的类型

                     short nodeType =node.getNodeType();

                     if(nodeType ==Node.ELEMENT_NODE)//Node.ELEMENT_NODE的值为1;

                     {

                            //是元素,继续递归

                            parseElement((Element)node);

                     }

                     else if(nodeType ==Node.TEXT_NODE)

                     {

                            //递归出口

                            System.out.print(node.getNodeValue());

                     }

                     else if(nodeType ==Node.COMMENT_NODE)

                     {

                            System.out.print("<!--");

                            Comment comment =(Comment)node;

                           

                            //注释内容

                            String data =comment.getData();

                            System.out.print(data);

                            System.out.print("-->");

                     }

              }

             

              System.out.print("</"+ tagName + ">");

       }

}

 

采用SAX解析下面的XML文档

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

<学生名册>

       <学生学号="t1">

              <姓名>张三</姓名>

              <性别>男</性别>

              <年龄>20</年龄>

       </学生>

</学生名册>

 

publicclass SaxTest1  //检验SAX按顺序解析XML:

{

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

       {

              //step1: 获得SAX解析器工厂实例

              SAXParserFactory factory =SAXParserFactory.newInstance();

             

              //step2: 获得SAX解析器实例

              SAXParser parser =factory.newSAXParser();

             

              //step3: 开始进行解析

              parser.parse(newFile("student.xml"), new MyHandler());

             

       }

}

 

classMyHandler extends DefaultHandler

{

       @Override

       public void startDocument() throwsSAXException

       {

              System.out.println("parsebegan");

       }

      

       @Override

       public void endDocument() throwsSAXException

       {

              System.out.println("parsefinished");

       }

      

       @Override

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

                     Attributes attributes)throws SAXException

       {

              System.out.println("startelement");

       }

      

       @Override

       public void endElement(String uri, StringlocalName, String qName)

                     throws SAXException

       {

              System.out.println("finishelement");

       }

}

 

采用Jdom解析下面的XML文档(开源框架)

 

publicclass JDomTest1

{

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

       {

              Document document = newDocument();

 

              Elementroot = new Element("root");

              document.addContent(root);//生成根元素

 

              Comment comment = newComment("This is my comments");//生成注释

       `      root.addContent(comment);注释加到根元素Element中

 

Element e = new Element("hello");//增加子元素

e.setAttribute("sohu","www.sohu.com");//子元素的属性

//一般Set方法不返回值,但此setAttribute返回Element值,这叫方法链的编程风格

//root.addContent(newElement("hello").setAttribute("a", "b")

//.setAttribute("x",y").setText("textcontent"));//给元素添加文本内容

 

root.addContent(e);

Format format =Format.getPrettyFormat();//控制生成的格式

XMLOutputter out = new XMLOutputter(format);

out.output(document, newFileWriter("jdom.xml"));//将生成的XML文件定向到文件中。用字节流newFileOutputStream("jdom.xml");

 

Jdom中将已经存在的XML文件解析成得到元素并修改

public class JDomTest2

{

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

       {

              SAXBuilder builder = new SAXBuilder();//SAXBuilder是一个解析器

              Document doc = builder.build(newFile("jdom.xml"));

             

              Element root= doc.getRootElement();//得到根元素

              System.out.println(element.getName());

             

              Element hello = element.getChild("hello");

              System.out.println(hello.getText());//得到子元素里的内容

             

              List list = hello.getAttributes();//返回的是元素的集合

for(inti = 0 ;i < list.size(); i++)

           {

                  Attribute attr =(Attribute)list.get(i);//得到元素

                 

                  String attrName =attr.getName();

                  String attrValue =attr.getValue();

                  System.out.println(attrName +"=" + attrValue);

           }

          

           hello.removeChild("world");//删除hello的子元素

XMLOutputter out = newXMLOutputter(Format.getPrettyFormat().setIndent("    "));

out.output(doc, newFileOutputStream("jdom2.xml"));//将新生成的文件定向到一个新文件中           

}

}

采用Dom4j解析生成XML文档(另一个开源框架)

public class Test1

{

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

       {

              // 创建文档并设置文档的根元素节点 :第一种方式

              // Document document = DocumentHelper.createDocument();

//Element root = DocumentHelper.createElement("student");

              // document.setRootElement(root);

 

              // 创建文档并设置文档的根元素节点 :第二种方式

              Element root =DocumentHelper.createElement("student");

              Document document =DocumentHelper.createDocument(root);//参数不一样

 

              root.addAttribute("name","zhangsan");

 

              Element helloElement = root.addElement("hello");//添加一个元素到根上面

              Element worldElement =root.addElement("world");

 

              helloElement.setText("hello");//设置元素的文本

              worldElement.setText("world");

 

              helloElement.addAttribute("age","20");//设置元素的属性

 

              1 XMLWriter xmlWriter = new XMLWriter();//创建并输出到命令行的控制台上

              xmlWriter.write(document);

             

2 OutputFormatformat = new OutputFormat("   ", true);//Format I不同于JDOM中的Format中的使用,有四个缩进。

XMLWriterxmlWriter2 = new XMLWriter(new FileOutputStream("student2.xml"),format); //字节流方式输出

              xmlWriter2.write(document);

              //将编码格式和输出一起写出到文件中。

3 XMLOutputter out= newXMLOutputter(Format.getPrettyFormat()

.setIndent("   ").setEncoding("gbk"));

out.output(document, new FileWriter("student2.xml"));

             

4 XMLWriterxmlWriter3 = new XMLWriter(new FileWriter("student3.xml"), format);//字符流方式输出,适用于UTF-8的编码。

              xmlWriter3.write(document);

              //xmlWriter3.flush();

              xmlWriter3.close();//会先调用flush()方法。

}

}

 

Dom4j中根据以上生成的XML文件进行解析出获取各种元素:

public class Test2

{

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

       {

              SAXReader saxReader = new SAXReader();

              Document doc = saxReader.read(newFile("student2.xml"));

Elementroot = doc.getRootElement();//得到根元素

ListchildList = root.elements();//得到所有的根元素下的子元素

ListchildList2 = root.elements("hello");//返回所有名为hello的子元素.

//采用跌带的方法获取root 下的子元素:

for(Iteratoriter = root.elementIterator(); iter.hasNext();)

           {

                  Element e =(Element)iter.next();

                  System.out.println(e.attributeValue("age"));//属性名字为age的元素

           }

              DocumentBuilderFactorydbf = DocumentBuilderFactory.newInstance();

              DocumentBuilder db = dbf.newDocumentBuilder();//获取Document解析对象

org.w3c.dom.Documentdocument= db.parse(new File("student2.xml"));//开始获得Document对象,必须加上包的名字,不然会混淆了W3C里的Document转化成dom4j里的

             

              DOMReader domReader =new DOMReader();

              //将JAXP的Document转换为dom4j的Document

Document d =domReader.read(document);//这个Document是JAXP里的,dom4j里的Document还没有生成

             

              Element rootElement = d.getRootElement();

              System.out.println(rootElement.getName());

 

 

XML Schema学习总结

 

简单类型 : 

1、简单元素:指只能包含文本内容,不能够包含子元素,也没有属性的元素。  

格式:<xs:elementname="xxx" type="yyy"/>  

例子:  

<xs:elementname="name" type="xs:string"/>  

<xs:elementname="age" type="xs:integer"/>  

<xs:elementname="gender" type="xs:boolean"/>  

 2、属性:所有的元素属性均被声明为简单类型。只有复杂类型的元素才可以拥

有属性。  

格式:<xs:attributename="xxx" type="yyy"/>  

例子:<xs:attributename="lang" type="xs:string"/>  

所有的属性默认都是可选的,我们可以通过使用use关键字明确的指出是可选或是必需:  

<xs:attributename="lang" type="xs:string"use="optional"/>  

<xs:attributename="lang" type="xs:string"use="required"/>  

 

我们可以通过使用default或fixed为简单类型(简单元素、属性)指定默认值或固定值,  

如下:  

<xs:elementname="color" type="xs:string"default="red"/>  

<xs:attributename="lang" type="xs:string" fixed="CN"/>  

 

对简单类型值的约束  

约束               含义 

enumeration     定义允许值的枚举 

fractionDigits     指定最多允许的小数位数(必须大于或等于零) 

length                  精确指定允许的最大字符长度 

maxExclusive     指定允许的最大数值,必须小于该值 

maxInclusive     指定允许的最大数值,必须小于或等于该值 

maxLength      指定允许的最大字符长度(必须大于等于零) 

minExclusive     指定允许的最小数值,必须大于该值 

minInclusive     指定允许的最小数值,必须大于或等于该值 

minLength           指定允许的最小字符长度 

pattern               指定允许值的模式,类似正则表达式 

totalDigits           精确指定数字个数 

whiteSpace         处理空白(保留:preserve;替换:replace;合并:collapse)

 

复杂类型  

 复杂类型指包含其他元素/属性的元素类型。  

 <message>  

<to>rose</to>  

<from>alex</from>  

<body>Hi,MyGirl!</body>  

</message>  

 

 在上面的例子中,元素 message 就是一个复杂类型的元素,我们在Schema中这样描述:  

<xs:elementname="message">  

<xs:complexType>  

<xs:sequence>  

<xs:elementname="to" type="xs:string"/>  

<xs:elementname="from" type="xs:string"/>  

<xs:elementname="body" type="xs:string"/>  

</xs:sequence>  

</xs:complexType>  

注意元素to,from,body 包含在<xs:sequence></xs:sequence>中,表明这些元素必须按照定义的顺序出现在你的XML 文件中。  当然,message 元素也可以包含一个 type属性,指向我们定义的复杂类型,象这样:  

<xs:elementname="message" type="msg"/>  

<xs:complexTypename="msg">  

<xs:sequence>  

<xs:elementname="to" type="xs:string"/>  

<xs:elementname="from" type="xs:string"/>  

<xs:elementname="body" type="xs:string"/>  

</xs:sequence>  

</xs:complexType>  

复杂类型和简单类型之间最根本的区别就是:复杂类型的内容中可以包含其他元素,也可以带有属性(Attribute),但简单类型既不能包含子元素,也不能带有任何属性。  

 

1、如何描述空元素,比如:<product prodid="1345" />?  

因为是空元素,所以不包含子元素,同时由于包含属性,用 attribute定义,象这样:  

<xs:elementname="product">  

<xs:complexType>  

<xs:attributename="prodid" type="xs:positiveInteger"/>  

</xs:complexType>  

</xs:element>  

也可以这样:  

<xs:elementname="product" type="productType"/>  

<xs:complexTypename="productType">  

<xs:attributename="prodid" type="xs:positiveInteger"/>  

</xs:complexType>  

2、如何描述只含有简单内容(文本/属性)的元素,比如:  

<messagedate="2006-06-26">Hi,My Girl!</message>?  

由于只包含简单内容,所以我们在元素内容定义的外面用 simpleContent  指 出,当描述简单内容的时候,我们需要在简单内容里使用 extension或者 restriction来描述内容的数据类型。象这样:  

 <xs:elementname="message">  

<xs:complexType>  

<xs:simpleContent>  

<xs:extensionbase="xs:string">  

<xs:attributename="date" type="xs:date" />  

</xs:extension>  

</xs:simpleContent>  

</xs:complexType>  

</xs:element>  

 

其中message 的属性date的数据类型为日期(xs:date)。  

顺便提一下:XML Schema中常用的数据类型有:  

xs:string  、xs:decimal  、xs:integer  、xs:boolean  、xs:date  、xs:time 等。  

3、如何定义混合类型,比如:  

<message>  

  This message comes from<from>Alex</from>  

</message>  

message元素除了包含子元素 from之外,还直接包含文本“This message comes from”。对于这种情况,我们需要在 complexType 中使用属性 mixed="true"指出。以下是 Schema:  

 <xs:elementname="message">  

<xs:complexTypemixed="true">  

<xs:elementname="from" type="xs:string"/>  

</xs:complexType>  

</xs:element>  

2、sequence:子元素在XML文件中按照XML Schema 定义的顺序出现。  

3、choice:两个或多个子元素中仅出现一个。例如:  

 <xs:elementname="gender">  

<xs:complexType>  

<xs:choice>  

<xs:elementname="male" type="male"/>  

<xs:elementname="female" type="female"/>  

</xs:choice>  

</xs:complexType>  

</xs:element>  

二、次数限定类,包括 minOccurs和maxOccurs,前者指定最少出现次数,后者指定最多出现次数。例如:  

<xs:elementname="person">  

<xs:complexType>  

<xs:sequence>  

<xs:elementname="full_name" type="xs:string"/>  

<xs:elementname="child_name" type="xs:string"  

maxOccurs="10"minOccurs="0"/>  

</xs:sequence>  

</xs:complexType>  

</xs:element>  

如果元素出现的最大次数无限制,可以使用maxOccurs="unbounded"。

三、组限定:包括Group和attributeGroup,用来定义一组相关的元素。比

如:  

<xs:groupname="persongroup">  

<xs:sequence>  

<xs:elementname="firstname" type="xs:string"/>  

<xs:elementname="lastname" type="xs:string"/>  

<xs:elementname="birthday" type="xs:date"/>  

</xs:sequence>  

</xs:group>      

--------------------------------------------------------------------------------------------------------------  

 <xs:attributeGroupname="personattrgroup">  

<xs:attributename="firstname" type="xs:string"/>  

<xs:attributename="lastname" type="xs:string"/>  

<xs:attributename="birthday" type="xs:date"/>  

</xs:attributeGroup>  

补充:<any>和<anyAttribute>  ,在XML Schema中使用这两个元素可以放宽Schema对XML文件内容的限制。容许我们在XML文件中使用没有在 Schema中定义的元素和属性。(很少使用)元素属性substitutionGroup可以让元素b替换元素a在XML文件中出现。 比如:  

<xs:elementname="cn_name" type="xs:string"/>  

<xs:elementname="en_name" substitutionGroup="cn_name"/>  

这种情形类似choice:  

<xs:choice>  

<xs:elementname="cn_name" type="xs:string"/>  

<xs:elementname="en_name" type="xs:string"/>  

</xs:choice>

 



















-----------------------------android培训java培训期待与您交流!----详细请查看:http://edu.youkuaiyun.com/heima---------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值