記事ディレクトリ
1 XML 解析
1.1 分析の概要
データを XML で保存した後、プログラムを通じて XML の内容を取得したいと考えています。Java の基礎を使って学習した IO の知識は完了しますが、完了するには非常に面倒な操作が必要であり、開発中にさまざまな問題 (読み取り専用、読み取り書き込み) に遭遇します。
人々はさまざまな問題に対してさまざまな解析方法を提供し、解析にさまざまなパーサーを使用します。これは開発者が XML を操作するのに便利です。
1.2 解析メソッドとパーサ
開発中の一般的な解析方法は次の 3 つです。
-
DOM : パーサーは、XML ドキュメント全体をメモリにロードし、それを Document オブジェクトに解析する必要があります。
a) 利点: 要素間の構造的関係が保持されるため、追加、削除、変更、およびクエリ操作を実行できます。
b) 欠点: XML ドキュメントが大きすぎるため、メモリ オーバーフローが発生する可能性があります。
-
SAX : より高速で効率的な方法です。ドキュメントを 1 行ずつスキャンし、進行中に解析します。そして、特定の分析はイベント駆動型で実行され、行が実行されるたびに対応するイベントがトリガーされます。
a) 利点: 処理速度が速く、大きなファイルを処理できる
b) 欠点: 読み取りのみ可能で、リソースは 1 行ずつ解放されるため、解析操作が面倒です。
-
PULL : SAX に似た Android の組み込み XML 解析メソッド。(学び)
パーサーは、さまざまな解析方法に従って特定の実装を提供します。一部のパーサーは操作が面倒なので、開発者の利便性を考慮して、操作が簡単な解析開発キットが用意されています。
一般的なパーサー
2 Dom4jの基本的な使い方
2.1 DOMの解析原理と構造モデル
分析原理
XML ドキュメント全体をメモリにロードし、DOM ツリーを生成し、DOM ツリーを操作できる Document オブジェクトを取得します。次のbooks.xmlドキュメントを例として取り上げます。
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="0001">
<name>JavaWeb开发教程</name>
<author>张孝祥</author>
<sale>100.00元</sale>
</book>
<book id="0002">
<name>三国演义</name>
<author>罗贯中</author>
<sale>100.00元</sale>
</book>
</books>
構造モデル
DOM の中心となる概念はノードです。XML ドキュメント内の要素、属性、テキストはすべて DOM のノードです。すべてのノードは Document オブジェクトにカプセル化されます。
結論は: Document オブジェクトを使用して、DOM ツリー内のすべてのノードにアクセスします
dom4jのjarパッケージを導入する
公式 Web サイトにアクセスして、zip パッケージをダウンロードします。http://www.dom4j.org/
通常、プロジェクト内に lib フォルダーを作成し、依存する必要があるライブラリをここに置きます。
ライブラリをインポートする方法:
-
IDEA で、プロジェクトを右クリックして、ポップアップ メニューを選択し、「モジュール設定を開く」>依存関係を選択し、±->JAR またはディレクトリを選択します。dom4j-1.6.1.jar を見つけ、追加後に「OK」をクリックします。成功しました。
-
直接右クリックして選択します: ライブラリとして追加
2.2 一般的に使用される方法
dom4j は、コア クラス SaxReader を使用して XML ドキュメントをロードして Document を取得し、Document オブジェクトを通じてドキュメントのルート要素を取得することで操作できるようになります。
SAXReader オブジェクト
方法 | 効果 |
---|---|
SAXReader sr = 新しい SAXReader(); | コンストラクタ |
ドキュメント読み取り(文字列URL) | XMLドキュメントをロードして実行します。 |
ドキュメントオブジェクト
方法 | 効果 |
---|---|
要素のgetRootElement() | ルート要素を取得する |
要素オブジェクト
方法 | 効果 |
---|---|
List<Element> 要素(String ele ) | 指定された名前のすべての子要素を取得します。名前は指定できません |
要素要素(String ele) | 指定された名前を持つ最初の子要素を取得します。 |
文字列 getName() | 現在の要素の要素名を取得します |
文字列属性値(文字列属性名) | 指定された属性名の属性値を取得します |
文字列要素テキスト(Sting ele) | 指定された名前の子要素のテキスト値を取得します |
文字列 getText() | 現在の要素のテキストコンテンツを取得します |
まとめ
XML を解析する手順:
- SaxReader オブジェクトを作成し、read メソッドを呼び出して XML ファイルを関連付け、Document オブジェクトを取得します。
- Document オブジェクトを通じてルート要素を取得します
- ルート要素を取得したら、それをレイヤーごとに剥離し、要素関連の API を使用してそのサブ要素を解析できます。
2.3 メソッドのデモンストレーション
よく使うxmlの「books.xml」をデータ配下にコピーすると、内容は以下のようになります。
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="0001">
<name>JavaWeb开发教程</name>
<author>张孝祥</author>
<sale>100.00元</sale>
</book>
<book id="0002">
<name>三国演义</name>
<author>罗贯中</author>
<sale>100.00元</sale>
</book>
</books>
注: 解析を容易にするため、この XML には制約は追加されていません。
このファイルを解析して、各書籍の ID 値、書籍名、著者名、価格を取得します。
ステップ分析:
- SaxReader オブジェクトを作成し、read メソッドを呼び出して XML ファイルをロードし、ドキュメント オブジェクトを取得します。
- ドキュメントオブジェクトを通じてルート要素を取得する
- サブ要素は、ルート要素を通じてレイヤーごとに解析されます。
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.List;
public class Demo01 {
public static void main(String[] args) throws DocumentException {
//1. 创建一个SaxReader对象,调用read方法加载一个xml文件获得文档对象
SAXReader sr = new SAXReader();
Document doc = sr.read("day15/xml/book.xml");
//2. 通过文档对象,获取根元素
Element rootElement = doc.getRootElement();
//3. 通过根元素一层一层的进行解析子元素。
//获取所有的子元素
List<Element> bookElements = rootElement.elements("book");
for (Element bookElement : bookElements) {
//System.out.println(bookElement);
//解析属性
String id = bookElement.attributeValue("id");
System.out.println("id = " + id);
//获取子元素文本
String name = bookElement.elementText("name");
String author = bookElement.elementText("author");
String sale = bookElement.elementText("sale");
System.out.println("name = " + name);
System.out.println("author = " + author);
System.out.println("sale = " + sale);
System.out.println("----------------------");
}
}
}
要件 2:
XML 内のファイル データを Java オブジェクトに解析し、各書籍を書籍タイプのオブジェクトに解析します。次に、book オブジェクトをコレクションに保存します。
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="0001">
<name>JavaWeb开发教程</name>
<author>张孝祥</author>
<sale>100.00元</sale>
</book>
<book id="0002">
<name>三国演义</name>
<author>罗贯中</author>
<sale>100.00元</sale>
</book>
</books>
ステップ分析:
- まずbook要素に対応するBookクラスを作成します。
- ArrayList コレクションを作成して、解析された書籍オブジェクトを保存します。
- SaxReader オブジェクトを作成し、read メソッドを呼び出して XML ファイルをロードし、ドキュメント オブジェクトを取得します。
- ドキュメント オブジェクトを通じてルート要素を取得し、それをレイヤーごとに解析します
コード:
public class Demo02 {
public static void main(String[] args) throws DocumentException {
//定义一个集合用来存储解析的Book对象
ArrayList<Book> books = new ArrayList<>();
//1. 创建一个SaxReader对象,调用read方法加载一个xml文件获得文档对象
SAXReader sr = new SAXReader();
Document doc = sr.read("day15/xml/book.xml");
//2. 通过文档对象,获取根元素
Element rootElement = doc.getRootElement();
//3. 通过根元素一层一层的进行解析子元素。
//获取所有的子元素
List<Element> bookElements = rootElement.elements("book");
for (Element bookElement : bookElements) {
//System.out.println(bookElement);
//解析属性
String id = bookElement.attributeValue("id");
System.out.println("id = " + id);
//获取子元素文本
String name = bookElement.elementText("name");
String author = bookElement.elementText("author");
String sale = bookElement.elementText("sale");
//将解析的字符串封装成为对象,放到集合
Book book = new Book(id,name,author,sale);
books.add(book);
}
//将集合遍历,打印book对象
for (Book book : books) {
System.out.println("book = " + book);
}
}
}
class Book{
private String id;
private String name;
private String author;
private String sale;
public Book() {
}
public Book(String id, String name, String author, String sale) {
this.id = id;
this.name = name;
this.author = author;
this.sale = sale;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getSale() {
return sale;
}
public void setSale(String sale) {
this.sale = sale;
}
@Override
public String toString() {
return "Book{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", author='" + author + '\'' +
", sale='" + sale + '\'' +
'}';
}
}