1. 程式人生 > >用java去解析一個最簡單的XML檔案

用java去解析一個最簡單的XML檔案

此處僅僅是去解析最基本的XML檔案,XML檔案如下:
<Books>
    <Book>
        <Name>Java入門</Name>
        <Price>30.00</Price>
    </Book>
    <Book>
        <Name>Java基礎</Name>
        <Price>130.00</Price>
    </Book>
    <Book>
        <Name>Java精通</Name>
        <Price>
256.00</Price> </Book> <Book> <Name>Java進階</Name> <Price>998.00</Price> </Book> <Book> <Name>程式設計師之禪</Name> <Price>122.00</Price> </Book> <Book> <Name>頸椎指南</Name>
<Price>50.00</Price> </Book> <Book> <Name>活著</Name> <Price>26.00</Price> </Book> <Book/> </Books>

上圖是一個書的XML檔案,我們建立一個Book類用來儲存上面的圖書實體

package learn;
public class Book implements Comparable<Book>{
    private 
String name; private float price; public Book() { } public Book(String name, float price) { this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", price=" + price + '}'; } @Override public int hashCode() { System.out.println("Book.hashCode"); return ((int) price); } @Override public boolean equals(Object obj) { System.out.println("Book.equals"); if (obj instanceof Book) { Book book = (Book) obj; return price == book.price && name.equals(book.name); } return false; } @Override public int compareTo(Book o) { int result = (int) (price - o.price); if (result == 0) { result = name.compareTo(o.name); } return result; } }
下面是解析XML的程式碼
package learn;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test01 {
    public static void main(String[] args) {
        String str = "<Books>\n" +
                "    <Book>\n" +
                "        <Name>Java入門</Name>\n" +
                "        <Price>30.00</Price>\n" +
                "    </Book>\n" +
                "    <Book>\n" +
                "        <Name>Java基礎</Name>\n" +
                "        <Price>130.00</Price>\n" +
                "    </Book>\n" +
                "    <Book>\n" +
                "        <Name>Java精通</Name>\n" +
                "        <Price>256.00</Price>\n" +
                "    </Book>\n" +
                "    <Book>\n" +
                "        <Name>Java進階</Name>\n" +
                "        <Price>998.00</Price>\n" +
                "    </Book>\n" +
                "    <Book>\n" +
                "        <Name>程式設計師之禪</Name>\n" +
                "        <Price>122.00</Price>\n" +
                "    </Book>\n" +
                "    <Book>\n" +
                "        <Name>頸椎指南</Name>\n" +
                "        <Price>50.00</Price>\n" +
                "    </Book>\n" +
                "    <Book>\n" +
                "        <Name>活著</Name>\n" +
                "        <Price>26.00</Price>\n" +
                "    </Book>\n" +
                "    <Book/>\n" +
                "</Books>";
List<Book> list = null;
Stack<Book> stack = new Stack<>();
Pattern pattern = Pattern.compile("<(/?)([^<>/]+)(/?)>");//此正則可能匹配到的是<>
Matcher matcher = pattern.matcher(str);
Stack<Integer> last = new Stack<>();//用來存放匹配到的<>,裡面沒有/,記錄匹配到的<>的末尾位置
        while (matcher.find()) {
            if (matcher.group(1).isEmpty()) {  //如果<...>裡面的首個括號內是空
                last.push(matcher.end());      //記錄匹配到的<...>的末尾位置
                switch (matcher.group(2)) {
                    case "Books":
                        list = new ArrayList<>();
                        break;
                    case "Book":
                        stack.push(new Book());
                        break;
}
                if (!matcher.group(3).isEmpty()) {  //匹配第三個括號裡有/,即<../>
                    last.pop();                     //匹配到<../>,棧頂元素出棧
                    switch (matcher.group(2)) {
                        case "Book":
                            list.add(stack.pop());
                            break;
}

                }
            } else {
//如果</...>裡面的首個括號內不是空
Integer pop = last.pop(); //記錄上一個<..>或<../>的matcher.end() switch (matcher.group(2)) { case "Book": list.add(stack.pop()); break; case "Name": stack.peek().setName(str.substring(pop, matcher.start())); break; case "Price": stack.peek().setPrice(Float.parseFloat(str.substring(pop, matcher.start()))); break;} } } for (Book book : list) { //遍歷得到的list,裡面存入的是Book的實體 System.out.println(book);} }}