[プロジェクト戦闘への Android エントリ -- 8.3] -- XML 形式のデータを解析する方法

目次

1.準備

EasyWebサーバー

2.プル解析方法

三、SAX分析法


        サーバーにデータを送信したり、データを取得したりできますが、データの交換はコンテンツだけでなく、データの属性と機能についても行われます. 相手がデータメッセージを受信すると、データメッセージに従って解析できます.同じ構造仕様ですので、必要な部分を取り出してください。

        Web を介してデータを転送する際に最も一般的に使用される形式は、XML と JSON の 2 つです。

1.準備

        次に、XML 形式のデータを取得する必要があります。最初に単純なサーバーを構築し、サーバーで XML テキストを取得します。ここでは、EasyWebServerを使用して小さなサーバーを構築します。

EasyWebサーバー

        EasyWebServer は、小さな Web サーバー ソフトウェアです。IIS などの巨大で複雑なツールを必要とせずに、PC に非常に迅速にサイトを作成できます。

ダウンロードアドレス:[EasyWebServer ウェブサイトサーバーのダウンロード] 2022 年に EasyWebServer ウェブサイトサーバーの最新の公式バージョンを無料でダウンロード - Tencent Software Center 公式サイト

ダウンロードが完了したら、ソフトウェアを開き、

[設定] をクリックすると、メイン ディレクトリが共有フォルダーになり、ファイル内に HTML ファイルが作成されます。

 

         次に、ブラウザーに IP を入力して、共有フォルダーの内容を表示します。

        携帯電話でローカル エリア ネットワークを形成する場合は、携帯電話で Web ページを開き、次の操作を続行できます。携帯電話のホットスポットを開き、ノートブックを携帯電話のホットスポットに接続します。ノートブックで取得した IP を確認し、サーバーを起動し、取得したノートブックをモバイル ブラウザーで開きます.ip に成功すると、共有フォルダーに HTML ファイルが表示されます。

        上記の操作が成功したら、Web ページ ディレクトリに get_data.xml ファイルを作成し、次の内容を追加します。

<apps>
	<app>
		<id>1</id>
		<name>Google Maps</name>
		<version>1.0</version>
	</app>
	<app>
		<id>2</id>
		<name>Chrome</name>
		<version>2.1</version>
	</app>
	<app>
		<id>3</id>
		<name>Goole Play</name>
		<version>2.3</version>
	</app>
</apps>

    準備作業が完了し、次の XML データが取得され、Android プログラムで解析されます。

2.プル解析方法

次に、NetworkTest プロジェクトで開発を続けます.ネットワークへの HTTP アクセスを学ぶために、最初にこの記事に移動できます.

MainActivity コードを次のように変更します。

        最初に、HTTP リクエストのアドレスを ip+get_data.xml に変更します。人によって異なります。変更に注意してください。次に、parseXMLWithPull(responseData) メソッドを呼び出して、サーバーから返されたデータを解析します。

        parseXMLWithPull() メソッドのコードは、最初に XmlPullParserFactory インスタンスを取得して XmlPullParse オブジェクトを取得し、次にこのオブジェクトの setInput() メソッドを呼び出して、サーバーから返された XML データを設定し、解析できるようにします。

        解析プロセス: 現在の解析イベントは getEventType() を介して取得でき、ループ内で解析されます。現在の解析イベントが XmlPullParser.END_DOCUMENT と等しくない場合、解析が完了していないことを意味し、次のイベントを実行できます。 next() メソッドを呼び出すことで解析されます。

        ループ内で、getName() を介して現在のノードの名前を取得します。ノード名が ID、名前、またはバージョンと等しい場合は、nextText() メソッドを呼び出して特定のコンテンツを取得します。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    TextView responseText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button sendRequest = (Button) findViewById(R.id.send_request);
        responseText = (TextView) findViewById(R.id.response_text);
        sendRequest.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.send_request) {
            sendRequestWithOkHttp();
        }
    }

    private void sendRequestWithOkHttp() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
                            .url("http://192.168.30.175/get_data.xml")
                            .build();
                    Response response = client.newCall(request).execute();
                    String responseData = response.body().string();
                    parseXMLWithPull(responseData);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }



    private void parseXMLWithPull(String xmlData) {
        try {
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlPullParser xmlPullParser = factory.newPullParser();
            xmlPullParser.setInput(new StringReader(xmlData));
            int eventType = xmlPullParser.getEventType();
            String id = "";
            String name = "";
            String version = "";
            while (eventType != XmlPullParser.END_DOCUMENT) {
                String nodeName = xmlPullParser.getName();
                switch (eventType) {
                    // 开始解析某个结点
                    case XmlPullParser.START_TAG: {
                        if ("id".equals(nodeName)) {
                            id = xmlPullParser.nextText();
                        } else if ("name".equals(nodeName)) {
                            name = xmlPullParser.nextText();
                        } else if ("version".equals(nodeName)) {
                            version = xmlPullParser.nextText();
                        }
                        break;
                    }
                    // 完成解析某个结点
                    case XmlPullParser.END_TAG: {
                        if ("app".equals(nodeName)) {
                            Log.d("MainActivity", "id is " + id);
                            Log.d("MainActivity", "name is " + name);
                            Log.d("MainActivity", "version is " + version);
                        }
                        break;
                    }
                    default:
                        break;
                }
                eventType = xmlPullParser.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

効果は次のとおりです。

ボタンクリック後のログ確認

三、SAX分析法

        SAX 構文解析の使用法は、Pull 構文解析よりも少し複雑ですが、意味的にはより明確になります。

DefaultHand から継承する新しい ContentHandler クラスを作成し、親クラスの 5 つのメソッドを次のように書き換えます。

        XML 解析を開始するときに startDocument() メソッドが呼び出され、ノードの解析を開始するときに startElement() メソッドが呼び出され、ノードのコンテンツを取得するときに characters() が呼び出され、ノードのコンテンツを取得するときに endElement() メソッドが呼び出されます。特定のノード node を解析すると、XML 解析全体が完了すると endDocument() が呼び出されます。

public class ContentHandler extends DefaultHandler {

    private String nodeName;

    private StringBuilder id;

    private StringBuilder name;

    private StringBuilder version;

    @Override
    public void startDocument() throws SAXException {
        id = new StringBuilder();
        name = new StringBuilder();
        version = new StringBuilder();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        // 记录当前结点名
        nodeName = localName;
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        // 根据当前的结点名判断将内容添加到哪一个StringBuilder对象中
        if ("id".equals(nodeName)) {
            id.append(ch, start, length);
        } else if ("name".equals(nodeName)) {
            name.append(ch, start, length);
        } else if ("version".equals(nodeName)) {
            version.append(ch, start, length);
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if ("app".equals(localName)) {
            Log.d("ContentHandler", "id is " + id.toString().trim());
            Log.d("ContentHandler", "name is " + name.toString().trim());
            Log.d("ContentHandler", "version is " + version.toString().trim());
            // 最后要将StringBuilder清空掉
            id.setLength(0);
            name.setLength(0);
            version.setLength(0);
        }
    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }

}

MainActivity コードを次のように変更します。

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    ...................

    private void sendRequestWithOkHttp() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
                            .url("http://192.168.30.175/get_data.xml")
                            .build();
                    Response response = client.newCall(request).execute();
                    String responseData = response.body().string();
                    parseXMLWithSAX(responseData);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }


    private void parseXMLWithSAX(String xmlData) {
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            XMLReader xmlReader = factory.newSAXParser().getXMLReader();
            ContentHandler handler = new ContentHandler();
            // 将ContentHandler的实例设置到XMLReader中
            xmlReader.setContentHandler(handler);
            // 开始执行解析
            xmlReader.parse(new InputSource(new StringReader(xmlData)));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

効果は Pull メソッドと同じです。

おすすめ

転載: blog.csdn.net/Tir_zhang/article/details/130462019