ホームページ >バックエンド開発 >XML/RSS チュートリアル >Javaでsaxを使用してxmlを解析するための解決策

Javaでsaxを使用してxmlを解析するための解決策

高洛峰
高洛峰オリジナル
2017-01-11 12:56:122325ブラウズ

Java では、XML ドキュメントをネイティブに解析する方法が 2 つあります。つまり、Dom 解析と Sax 解析です。

Dom 解析は強力で、操作中に XML ドキュメントが読み込まれます。ドキュメントオブジェクトの形式でメモリを保持するため、小さなドキュメントに適しています

Sax の解析では、内容を要素ごとに最初から最後まで読み取ります。変更するのはより不便ですが、大規模な読み取り専用に適しています。ドキュメント

この記事では主に Sax の解析について説明します。残りは省略します

Sax イベント駆動型のアプローチを使用してドキュメントを解析します。簡単に言うと、映画館で映画を観ているようなものです。最初から最後まで戻らずに見ることができます(ドムは前後に読むことができます)

映画を観ている途中で、毎回、プロット、涙、そして、どんなに肩をこすり合わせても、あなたはこの情報を受け取ったり処理したりするために脳と神経を総動員することになります

同様に、Sax の解析プロセスでは、文書の最初と最後、そして最初と最後を読みます。要素の末尾は、いくつかのコールバック メソッドをトリガーします。これらのコールバックを使用して、対応するイベント処理がメソッド内で実行されます

4 つのメソッドは、startDocument()、endDocument()、startElement()、endElementです

さらに、ノードを読み取るだけでは十分ではありません。要素に含まれるコンテンツを注意深く処理するには、characters() メソッドも必要です

これらのコールバック メソッドを集めてクラスを形成し、これが必要なトリガーになります

通常、ドキュメントは読み取られますMainメソッドからですが、ドキュメントはトリガー内で処理されます。これは、いわゆるイベント駆動型の解析方法です

Javaでsaxを使用してxmlを解析するための解決策

上の図に示すように、トリガーでは、最初にドキュメントの読み取りを開始し、次にドキュメントを読み取ります。要素の解析を 1 つずつ開始し、各要素の内容がcharacters() メソッドに返されます

次に、要素の読み取りを終了し、すべての要素が読み取られた後、ドキュメントの解析を終了します

次に、トリガー クラスの作成を開始します。このクラスを作成するには、まず DefaultHandler を継承する必要があります

SaxHandler を作成し、対応するメソッドをオーバーライドする必要があります:

import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 

  
public class SaxHandler extends DefaultHandler { 

    /* 此方法有三个参数 
       arg0是传回来的字符数组,其包含元素内容 
       arg1和arg2分别是数组的开始位置和结束位置 */ 
    @Override 
    public void characters(char[] arg0, int arg1, int arg2) throws SAXException { 
        String content = new String(arg0, arg1, arg2); 
        System.out.println(content); 
        super.characters(arg0, arg1, arg2); 
    } 

    @Override 
    public void endDocument() throws SAXException { 
        System.out.println("\n…………结束解析文档…………"); 
        super.endDocument(); 
    } 

    /* arg0是名称空间 
       arg1是包含名称空间的标签,如果没有名称空间,则为空 
       arg2是不包含名称空间的标签 */ 
    @Override 
    public void endElement(String arg0, String arg1, String arg2) 
            throws SAXException { 
        System.out.println("结束解析元素  " + arg2); 
        super.endElement(arg0, arg1, arg2); 
    } 

    @Override 
    public void startDocument() throws SAXException { 
        System.out.println("…………开始解析文档…………\n"); 
        super.startDocument(); 
    } 

    /*arg0是名称空间 
      arg1是包含名称空间的标签,如果没有名称空间,则为空 
      arg2是不包含名称空间的标签 
      arg3很明显是属性的集合 */
    @Override
    public void startElement(String arg0, String arg1, String arg2, 
            Attributes arg3) throws SAXException { 
        System.out.println("开始解析元素 " + arg2); 
        if (arg3 != null) { 
            for (int i = 0; i < arg3.getLength(); i++) { 
                 // getQName()是获取属性名称, 
                System.out.print(arg3.getQName(i) + "=\"" + arg3.getValue(i) + "\""); 
            } 
        } 
        System.out.print(arg2 + ":"); 
        super.startElement(arg0, arg1, arg2, arg3); 
    } 
}

XML ドキュメント:

<?xml version="1.0" encoding="UTF-8"?>  
<books>  
   <book id="001">  
      <title>Harry Potter</title>  
      <author>J K. Rowling</author>  
   </book>  
   <book id="002">  
      <title>Learning XML</title>  
      <author>Erik T. Ray</author>  
   </book>  
</books>

TestDemo テスト クラス:

import java.io.File; 

import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 

  
public class TestDemo { 

    public static void main(String[] args) throws Exception { 
        // 1.实例化SAXParserFactory对象 
        SAXParserFactory factory = SAXParserFactory.newInstance(); 
        // 2.创建解析器 
        SAXParser parser = factory.newSAXParser(); 
        // 3.获取需要解析的文档,生成解析器,最后解析文档 
        File f = new File("books.xml"); 
        SaxHandler dh = new SaxHandler(); 
        parser.parse(f, dh); 
    } 
}

出力結果:

…………开始解析文档………… 

开始解析元素 books 
books:  

开始解析元素 book 
id="001"book:  

开始解析元素 title 
title:Harry Potter 
结束解析元素  title 

        
开始解析元素 author 
author:J K. Rowling 
结束解析元素  author 

     
结束解析元素  book 

     
开始解析元素 book 
id="002"book:  

开始解析元素 title 
title:Learning XML 
结束解析元素  title 

        
开始解析元素 author 
author:Erik T. Ray 
结束解析元素  author 

     
结束解析元素  book 

  
结束解析元素  books 

…………结束解析文档…………

上記は実行を示していますが、正しく処理しても、出力は非常に乱雑になります

このプロセスをより明確に実行するために、SaxHandler を元の内容になるように書き換えることもできます。xml ドキュメントを再度復元します

書き換えられた SaxHandler クラス:

import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 

  
public class SaxHandler extends DefaultHandler { 

    @Override
    public void characters(char[] arg0, int arg1, int arg2) throws SAXException { 
        System.out.print(new String(arg0, arg1, arg2)); 
        super.characters(arg0, arg1, arg2); 
    } 

    @Override
    public void endDocument() throws SAXException { 
        System.out.println("\n结束解析"); 
        super.endDocument(); 
    } 

    @Override
    public void endElement(String arg0, String arg1, String arg2) 
            throws SAXException { 
        System.out.print("</"); 
        System.out.print(arg2); 
        System.out.print(">"); 
        super.endElement(arg0, arg1, arg2); 
    } 

    @Override
    public void startDocument() throws SAXException { 
        System.out.println("开始解析"); 
        String s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 
        System.out.println(s); 
        super.startDocument(); 
    } 

    @Override
    public void startElement(String arg0, String arg1, String arg2, 
            Attributes arg3) throws SAXException { 

        System.out.print("<"); 
        System.out.print(arg2); 

        if (arg3 != null) { 
            for (int i = 0; i < arg3.getLength(); i++) { 
                System.out.print(" " + arg3.getQName(i) + "=\"" + arg3.getValue(i) + "\""); 
            } 
        } 
        System.out.print(">"); 
        super.startElement(arg0, arg1, arg2, arg3); 
    } 

}

その他の関連記事については、 Sax を使用して Java で XML を解析する場合は、PHP の中国語 Web サイトに注意してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。