XML - XML 解析用の SAX

黄舟
リリース: 2017-02-24 15:06:59
オリジナル
1450 人が閲覧しました

1.SAX 解析

  • DOM を使用して XML ドキュメントを解析する場合、XML ドキュメント全体を読み取り、DOM ツリー全体の Document オブジェクトをメモリ内に構築してから、XML ドキュメントを操作する必要があります。 。この場合、XML ドキュメントが特に大きい場合は、コンピュータのメモリを大量に消費し、ひどい場合にはメモリ オーバーフローが発生することもあります。

  • SAX 解析を使用すると、文書を操作する前に文書全体がロードされるまで待つことなく、文書の読み取り時に文書を処理できます。

  • DefaultHandler

を継承してSAXパーサーを開発する [注意] SAXは主にXML文書の解析に使用され、要素の変更、削除、追加はできません。

1.1. SAX 解析メカニズム

sax はプッシュ メカニズムであり、XML ドキュメント内のコンテンツが見つかったときにパーサーが通知します (イベントをプッシュします)。 Java Swing でのイベント リスニングに多少似ています)。これらの結果をどう処理するかを決定するのはプログラマの責任です。

Sax ベースのプログラムでは、最も一般的に使用される 5 つの Sax イベントがあります:

1.startDocument()–> は、パーサーがドキュメントの先頭を見つけたことを示し、パーサーがスキャンを開始したことを示します。書類

2.endDocument()–> パーサーがドキュメントの終わりを見つけたことを示します
; 3.startElement()–> このイベントは、パーサーが開始タグを見つけたことを示し、要素のすべての属性名と値を示します。 4.characters()–> パーサーがテキストを見つけたことを示します。これらの 3 つの変数を使用して、パーサーが見つけたテキストを取得できます。 5.endElement()–> このイベントは、要素の名前を示します


引き続き、DOM 解析で使用される XML の例を使用します。
<?xml version="1.0" encoding="utf-8" standalone="no"?><班级>
    <学生 地址="香港">
        <名字>周小星</名字>
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
    </学生>
    <学生 地址="澳门">
        <名字>林晓</名字>
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生></班级>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

[手順]:

1. SAXParserFactory を使用して SAX 解析ファクトリーを作成します

SAXParserFactory spf = SAXParserFactory.newInstance();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

2. SAX 解析ファクトリーを通じてパーサー オブジェクトを取得します

SAXParser sp = spf.newSAXParser();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
3. 解析オブジェクトとイベント ハンドラーを関連付けます。 object

sp.parse("src/myClass.xml",new MyHandler());
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ここで、MyHandler は自分で定義する必要があり、

を継承してから、MyHandler クラスで上記の 5 つの Sax イベント メソッドを書き換える必要があります。 、必要なものを書き直すこともできます。

たとえば、今書いた MyHandler は次のとおりです:

class MyHandler extends DefaultHandler{    /**
     * 发现文档开始,该函数只会被调用一次
     */
    @Override
    public void startDocument() throws SAXException {
        System.out.println("startDocument");
    }    /**
     * 发现文档结束,该函数只会被调用一次
     */
    @Override
    public void endDocument() throws SAXException {
        System.out.println("endDocument");
    }    /**
     * 发现XML中的一个元素开始,会被反复调用
     */
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        System.out.println("元素名称:"+qName);
    }    /**
     * 发现XML中的一个元素结束,会被反复调用
     */
    @Override
    public void endElement(String uri, String localName, String qName)            
    throws SAXException {

    }    /**
     * 发现XML文件中的文本,会被反复调用
     */
    @Override
    public void characters(char[] ch, int start, int length)            
    throws SAXException {        // 显示文本内容
        String text = new String(ch,start,length);        if(!text.trim().equals("")){
            System.out.println(text);
        }
    }
}
ログイン後にコピー

実行結果は次のとおりです:

実行結果 1MyHandler需要自己定义,并且它要继承DefaultHandler,然后在MyHandler类中重写上文提到的5个sax事件方法,当然也可以只重写自己需要的。
比如现在我写的MyHandler如下:

private boolean isName = false;private boolean isAge = false;
ログイン後にコピー
ログイン後にコピー

运行结果如下:

XML - XML 解析用の SAX

可以看到,这是对XML文档的一种遍历,而sax能够做的也只是遍历了。


那么,如果现在我们有这样一个需求:只显示所有学生的姓名和年龄,不显示学生的介绍,怎么实现呢?

我们可以在MyHandler类中定义两个布尔变量isName和isAge,在startElement方法中标识是否是姓名元素或者年龄元素,如果是的话才在characters方法中获取对应的文本,如下:

1.定义两个布尔变量

@Overridepublic void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {    if(qName.equals("名字")){        this.isName = true;
    }else if(qName.equals("年龄")){        this.isAge = true;
    }
}
ログイン後にコピー

2.在startElement方法中添加判断

@Overridepublic void characters(char[] ch, int start, int length)        throws SAXException {    // 显示文本内容
    String text = new String(ch,start,length);    if(!text.trim().equals("")&&(isName||isAge)){
        System.out.println(text);
    }
    isName = false;
    isAge = false;
}
ログイン後にコピー
ログイン後にコピー

3.在characters方法中根据标识符进行判断是否获取文本

<?xml version="1.0" encoding="utf-8" standalone="no"?><班级>
    <学生 地址="香港">
        <名字>周小星</名字>
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
    </学生>
    <学生 地址="澳门">
        <名字>林晓</名字>
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生></班级>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

最后要记得将两个布尔变量复位成false。
运行结果如下:

XML - XML 解析用の SAX

1.SAX解析

  • 在使用DOM解析XML文档时,需要读取整个XML文档,在内存中构建整个DOM树的Document对象,从而再对XML文档进行操作。此种情况下,如果XML文档特别大,就会消耗计算机的大量内存,严重的情况下可能还会导致内存溢出。

  • SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才对文档进行操作。

  • 通过继承DefaultHandler

    これは XML ドキュメントのトラバースであることがわかります。sax ができるのはトラバースだけです。

それでは、次のような要件がある場合:
すべての生徒の名前と年齢のみを表示し、生徒の紹介は表示しない場合、どのように実装すればよいでしょうか?

MyHandler クラスで 2 つのブール変数 isName と isAge を定義し、startElement メソッドでそれが name 要素であるか age 要素であるかを識別できます。はいの場合は、次のように characters メソッドで対応するテキストを取得します。

1. 2 つのブール変数を定義します

SAXParserFactory spf = SAXParserFactory.newInstance();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
2. startElement に追加します。 > メソッド

SAXParser sp = spf.newSAXParser();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

を決定します。 3. characters メソッドで、識別子

🎜
sp.parse("src/myClass.xml",new MyHandler());
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
🎜 に基づいてテキストを取得するかどうかを判断します。 最後に、2 つのブール変数を false にリセットすることを忘れないでください。 🎜実行結果は以下の通りです: 🎜🎜XML - XML 解析用の SAX🎜🎜🎜1.SAX 解析🎜🎜🎜🎜🎜DOM を使用して XML ドキュメントを解析する場合、XML ドキュメント全体を読み取り、DOM ツリー全体の Document オブジェクトをメモリ内に構築してから、操作を行う必要があります。 XML ドキュメント。この場合、XML ドキュメントが特に大きい場合は、コンピュータのメモリを大量に消費し、ひどい場合にはメモリ オーバーフローが発生することもあります。 🎜🎜🎜🎜SAX 解析を使用すると、文書を操作する前に文書全体がロードされるまで待つことなく、文書の読み取り時に文書を処理できます。 🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜を継承してSAXパーサーを開発する [注意] SAXは主にXML文書の解析に使用され、要素の変更、削除、追加はできません。 🎜🎜🎜🎜🎜1.1. SAX 解析メカニズム 🎜🎜🎜sax はプッシュ メカニズムです。XML ドキュメント内のコンテンツが見つかった場合、パーサーはそれを通知します (イベントをプッシュします)。 Java Swing でイベントをリッスンする)。これらの結果をどう処理するかを決定するのはプログラマの責任です。 🎜🎜 サックスベースのプログラムでは、最も一般的に使用される 5 つのサックス イベントがあります: 🎜

1.startDocument()–>告诉你解析器发现了文档的开始,告诉你解析器开始扫描文档
2.endDocument()–>告诉你解析器发现了文档结尾
3.startElement()–>告诉你解析器发现了一个起始标签,该事件告诉你标签的名称、该元素所有的属性名和值
4.characters()–>告诉你解析器发现了一些文本,将得到一个字符数组,该数组的偏移量和一个长度偏移量,有这三个变量你可以得到解析器发现的文本
5.endElement()–>告诉你解析器发现了一个结束标签,该事件告诉你元素的名称

1.2.SAX解析实例

依然使用DOM解析中用到的XML例子,如下:

<?xml version="1.0" encoding="utf-8" standalone="no"?><班级>
    <学生 地址="香港">
        <名字>周小星</名字>
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
    </学生>
    <学生 地址="澳门">
        <名字>林晓</名字>
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生></班级>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

【步骤】:

1.使用SAXParserFactory创建SAX解析工厂

SAXParserFactory spf = SAXParserFactory.newInstance();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

2.通过SAX解析工厂得到解析器对象

SAXParser sp = spf.newSAXParser();
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

3.将解析对象和事件处理器对象关联

sp.parse("src/myClass.xml",new MyHandler());
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

这里的MyHandler需要自己定义,并且它要继承DefaultHandler,然后在MyHandler类中重写上文提到的5个sax事件方法,当然也可以只重写自己需要的。
比如现在我写的MyHandler如下:

class MyHandler extends DefaultHandler{    /**
     * 发现文档开始,该函数只会被调用一次
     */
    @Override
    public void startDocument() throws SAXException {
        System.out.println("startDocument");
    }    /**
     * 发现文档结束,该函数只会被调用一次
     */
    @Override
    public void endDocument() throws SAXException {
        System.out.println("endDocument");
    }    /**
     * 发现XML中的一个元素开始,会被反复调用
     */
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        System.out.println("元素名称:"+qName);
    }    /**
     * 发现XML中的一个元素结束,会被反复调用
     */
    @Override
    public void endElement(String uri, String localName, String qName)            
    throws SAXException {

    }    /**
     * 发现XML文件中的文本,会被反复调用
     */
    @Override
    public void characters(char[] ch, int start, int length)            
    throws SAXException {        // 显示文本内容
        String text = new String(ch,start,length);        
        if(!text.trim().equals("")){
            System.out.println(text);
        }
    }
}
ログイン後にコピー

运行结果如下:

XML - XML 解析用の SAX

可以看到,这是对XML文档的一种遍历,而sax能够做的也只是遍历了。


那么,如果现在我们有这样一个需求:只显示所有学生的姓名和年龄,不显示学生的介绍,怎么实现呢?

我们可以在MyHandler类中定义两个布尔变量isName和isAge,在startElement方法中标识是否是姓名元素或者年龄元素,如果是的话才在characters方法中获取对应的文本,如下:

1.定义两个布尔变量

private boolean isName = false;private boolean isAge = false;
ログイン後にコピー
ログイン後にコピー

2.在startElement方法中添加判断

@Overridepublic void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {    if(qName.equals("名字")){        
        this.isName = true;
    }else if(qName.equals("年龄")){        this.isAge = true;
    }
}
ログイン後にコピー

3.在characters方法中根据标识符进行判断是否获取文本

@Overridepublic void characters(char[] ch, int start, int length)        throws SAXException {    // 显示文本内容
    String text = new String(ch,start,length);    if(!text.trim().equals("")&&(isName||isAge)){
        System.out.println(text);
    }
    isName = false;
    isAge = false;
}
ログイン後にコピー
ログイン後にコピー

最后要记得将两个布尔变量复位成false。
运行结果如下:

XML - XML 解析用の SAX

 以上就是XML—XML解析之SAX的内容,更多相关内容请关注PHP中文网(www.php.cn)!


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート