XML及使用java解析XML

最近學習的心情

XML即Extensible Markup Language,可擴展標記語言,主要的應用有三方面:

1.存儲數據,這個沒什么好說的

2.傳輸數據,純文本文件,不存在轉換格式的麻煩

3.軟件配置,比如今后學的配置tomcat虛擬目錄映射等就用到了

那么直奔主題:

一、XML文件結構

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<!DOCTYPE root SYSTEM "path.dtd">
<root>
       .......
</root>

version是告訴瀏覽器使用什么版本的XML解析器,encoding是來設置文件的編碼,standalone表明XML是否引入了其他非XML文件如css、dtd文件

<!DOCTYPE ...>為內部或外部引入的DTD文件,DTD為Document Type Definition,用來定義合法的XML文件結構

<root></root>為XML的根節點,只能有一個,里面存儲自定義的標簽元素

1.標簽的書寫規范

XML語法嚴格,對大小寫敏感,不可間接嵌套;標簽名不能以數字、_下劃線、xml開頭;標簽名中不能出現空格、:

在XML中<,>,&,“,及逗號都是特殊字符,如要在標簽內部使用需要使用內部實體代替

<label attr=""></label>←跟html書寫很像不再贅述

<?xml version="1.1" encoding="UTF-8"?>
  <studentList>
    <student id="A01" class="A">
    <name>小明</name>
    <age>19</age>
    <gender>man</gender>
    <score>
      <subject name="Advanced Mathematics">90</>
      <subject name="College English">85</>
      <subject name="C++Programming">88</>
    </score>
  </student>
  <student id="A02" class="B">
    <name>小紅</name>
    <age>20</age>
    <gender>woman</gender>
    <score>
      <subject name="Data Structure">80</subject>
      <subject name="JavaProgramming">90</subject>
    </score>
  </student>
</studentList>

一個簡單的XML文件

2.CDATA區

所有 XML 文檔中的文本均會被解析器解析,只有 CDATA(Unparsed Character Data) 區段中的文本會被解析器忽略。

作用:因為XML中有特殊字符的存在(< > &等),所以我們在用XML傳送JavaScript代碼或者其他數據時,只要將內容聲明在CDATA區中就不會被瀏覽器解析,出錯。

使用方法:

<![CDATA[your data]]>

3.處理指令

<?xml-stylesheet type="text/css" href="path.css"?>
<?xml-stylesheet type="text/xsl href="path.xsl"?>
↑沒什么好說的

二、DTD語法

在XML文件內使用DTD格式為:

<!DOCTYPE 根標簽名稱 [ 
  <!ELEMENT>
  <!ATTLIST>
  <!ENTITY>
 ]>

在外部引入為:

<!DOCTYPE 根標簽名字 SYSTEM ”path.dtd“>

1.<!ELEMENT>定義元素

書寫格式:<!ELEMENT 標簽名 類別/(內容)>

其中類別值有EMPTY、ANY

()內填寫子標簽數量、順序描述,或對文本內容描述(#PCDATA)

對于子標簽數量,有+、*、?、|修飾,類似正則表達式不再贅述

對于順序描述,(name,age,gender,score)即表達了子標簽必須以此順序定義

PCDATA為Parsed Character Data可解析的字符內容,當標簽內只有文本內容(不含嵌套的標簽時)可以使用(#PCDATA)

EMPTY,ANY表示標簽內容可以是空的,空的或純文本

對上述XML文件進行定義
<!DOCTYPE studentList [
<!ELEMENT studenList (student+)>
<!ELEMENT student (name,(age?),(gender?),(score?))>     //名字最重要,其他信息可有可無
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT gender (#PCDATA)>
<!ELEMENT score (subject*)>
<!ELEMENT subject ANY>                   //這樣就表示支持<s></s>、<s>100</s>這兩種寫法
]>

DTD定義中必須將所有標簽元素全部定義完、屬性也是一樣的,上述DTD定義不完整,還缺少屬性定義

2.<!ATTLIST>定義屬性

<!ATTLIST 標簽名 屬性名 屬性類型 屬性約束>

屬性類型有

CDATA                               屬性值是字符數據 

ID                                  屬性值是唯一的一個以英文字母開頭的ID值

IDREF                               屬性值與同一標簽內ID型屬性的值相等

(en1|en2...)                        屬性值是枚舉中的一個

<!ATTLIST label name ID #REQUIRED nickname IDREF #REQUIRED>
則說明屬性nickname的值必須與name屬性的值相同

屬性約束有

“   ”                                   如果屬性為空,則默認等于“  ”內值

#REQUIRED                               屬性值是必需要填寫的,不能為空

#IMPLIED                                不必需,可空

#FIXED “ ”                              屬性值必填,必須與“ ”內值一樣

<!ATTLIST student id ID #REQUIRED class (A|B) #REQUIRED>
id屬性值為必填的ID類型,class屬性值為必填的、值只能為A或B的枚舉類型
<!ATTLIST subject name CDATA #IMPLIED>
name屬性的值為選填的字符類型

所以對開頭XML的完整DTD定義為

<!DOCTYPE root [
  <!ELEMENT>
   ...
  <!ATTLIST>
  ...
]>

3.<!ENTITY>定義實體

類似c語言#define

引用實體

<!ENTITY d "doctor">

<occupation>&d;</occupation> → 即為<occupation>doctor</occupation>

使用方法: &+實體+;

預定義好的引用實體:

&  \&     <  \<     >  \>     "  \"     '  \'

參數實體

<!ENTITY % order "name,age,gender,score">

顧名思義,參數實體只能用來替換DTD定義標簽中的參數

<!ELEMENT student (%order;)> → <!ELEMENT student (name,age,gender,score)>

參數實體定義位置必須位于使用之前,參數實體無法在內部DTD使用,只能在外部使用,一個XML文件只能有一個DTD文件約束

三、使用java解析XML

java不像js一樣提供對XML文檔的原生支持,我們通過使用dom4j的API來對XML進行操作

C++轉戰學java的心情

0.提前做好的準備工作

導好jar包
寫好一份XML文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE studentList SYSTEM "Demo.dtd">
<studentList>
    <student id="A01" class="A">
        <name>小明</name>
        <age>19</age>
        <gender>man</gender>
        <score>
            <averageScore>84.8</averageScore>
            <subject name="AdvancedMathematics">82</subject>
            <subject name="CollegeEnglish">86</subject>
            <subject name="C++">94</subject>
            <subject name="DataStructure">77</subject>
            <subject name="Java">85</subject>
        </score>
        <identity minority="">
            <position>monitor</position>
            <politicalStatus>communist youth league member</politicalStatus>
        </identity>
    </student>
    <student id="A02" class="B">
        <name>小紅</name>
        <age>20</age>
        <gender>woman</gender>
        <score>
            <averageScore>91</averageScore>
            <subject name="AdvencedMathematics">97</subject>
            <subject name="CollegeEnglish">89</subject>
            <subject name="C++">82</subject>
            <subject name="DataStructure">95</subject>
            <subject name="Java">92</subject>
        </score>
        <identity minority="壯族">
            <position></position>
            <politicalStatus>party member</politicalStatus>
        </identity>
    </student>
</studentList>
一份DTD文件

1.讀取XML文件

SAXReader saxReader = new SAXReader();
Document xml = saxReader.read(XMLparse.class.getClassLoader().getResource("Demo.xml"));    
//使用類加載器可以避免復雜的路徑。。。其實也沒方便多少
//saxReader.read(new File("C:\Users\15421\eclipse-workspace\XMLparse\src\Demo.xml"))
System.out.println(xml==null?"加載失敗":"加載成功");

2.實現增功能

/*--------創建小剛同學的XML結構--------*/
Element rootElement = xml.getRootElement();
System.out.println(rootElement.getName());
Element newElement = DocumentHelper.createElement("student");
newElement.addAttribute("id", "A03");
newElement.addAttribute("class", "A");
newElement.addElement("name").setText("小剛");
System.out.println("id: "+newElement.attributeValue("id")+"   class: "+newElement.attributeValue("class")+"   name: "+newElement.element("name").getText());
結果1
/*----------獲取節點列表,在小紅前添加小剛---------*/
List<Element> list = rootElement.elements("student");
Iterator<Element> iterator = list.iterator();    //使用集合類的迭代器iterator進行遍歷
int index = 0;
while(iterator.hasNext()) {
  Element element = iterator.next();
  if(element.elementText("name").equals("小紅")) {
    System.out.println("小紅在第"+index+"個上");
    list.add(index,newElement);    //插入小剛
    break;    //注意,在某些情況下不break會造成無限循環的后果(因為list已經變化了),這里倒沒有影響
  }
  ++index;
}
System.out.println("添加后:");
iterator = list.iterator();    //迭代器用完了就要換一個(不管原來List變化沒有),這里重新加載了一遍
while(iterator.hasNext()) {
  System.out.println(iterator.next().elementText("name"));
}
結果2

3.實現刪功能

iterator = list.iterator();
int index = 0;
while(iterator.hasNext()) {
  if(iterator.next().elementText("name").equals("小剛")) {
    list.remove(index);
    break; 
  }
  ++index;
}
iterator = list.iterator();
System.out.println("刪除后:");
for(Element element:list){
  System.out.println(element.elementText("name"));
}
結果3

4.實現查、改功能

/*--------------查找----------------*/
//使用xpath快速定位標簽
System.out.println("Java成績:");
String xpath = "http://subject[@name='Java']";    //在全體人員中查找name屬性為Java的subject標簽
List<Node> subjects = xml.selectNodes(xpath);
for(Node node:subjects) {
  System.out.println(node.getText());
}
//使用迭代器遍歷(霧)    你喜歡就好
iterator = list.iterator();
  for(;iterator.hasNext();) {
    List<Element> list2 = iterator.next().elements();
    Iterator<Element> iterator2 = list2.iterator();
    for(;iterator2.hasNext();) {
      Element element = iterator2.next();
      if(element.getName().equals("score")) {
        List<Element> list3 = element.elements();
        Iterator<Element> iterator3 = list3.iterator();
        for(;iterator3.hasNext();) {
          Element element2 = iterator3.next();
          if(element2.getName().equals("subject")&&element2.attributeValue("name").equals("Java")) {
            System.out.println(element2.getText());
        }
      }
    }
  }
}
結果4
/*-------------修改標簽屬性值/內容-------------*/
//1.修改小明少數民族為苗族
//2.修改全體人員職位為student
xpath = "student[@id='A01']//identity";
Element identity = (Element)xml.selectSingleNode(xpath);
identity.addAttribute("minority", "苗族");
//↑這里失敗了,原因是select方法返回的是Node類型,強制轉換后雖然能使用addAttribute方法但是報錯空指針
//以后再研究吧
xpath = "http://position";
List<Node> position_list = xml.selectNodes(xpath);
for(Node node:position_list) {
  node.setText("student");
}

5.向硬盤中輸出修改的XML

OutputStream os = new FileOutputStream(new File("C:\\Users\\15421\\Desktop\\demo_out.xml"));  
\\是轉義符哦
OutputFormat of = OutputFormat.createPrettyPrint();
//createCompactPrint 將去掉所有縮進
XMLWriter xml_out = new XMLWriter(os,of);
xml_out.write(xml);
xml_out.close();
結果5

小結

最近學的好雜啊。。。快爆炸了,我要寫物理實驗了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 經過兩天的奮戰,終于把xml簡略的過了一遍。 1.1XML介紹 xml是Extensible Markup lan...
    Ystrator閱讀 848評論 0 2
  • 1. XML簡介 以下內容來自于http://www.w3school.com.cn/xml 基本知識 XML 和...
    WebSSO閱讀 1,956評論 1 7
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,915評論 18 139
  • 大學生自習室的確是大學的一片凈土,無淪網絡上媒體上傳出過什么大學生自 習室的不良信息。但不可否認的是那些都是個...
    甜筒諾言閱讀 1,468評論 1 1
  • 10.28玉民日志 1.6:30起床 2.8:00-12:00收拾打掃家 3.13:00-15:00休息看書 4....
    Mr玉民閱讀 231評論 1 1