Tip Java 128: Buat pengurai XML cepat-dan-kotor

XML adalah format data yang populer karena beberapa alasan: XML dapat dibaca manusia, dijelaskan sendiri, dan portabel. Sayangnya, banyak pengurai XML berbasis Java berukuran sangat besar; misalnya, Sun Microsystems jaxp.jardan parser.jarperpustakaan masing-masing berukuran 1,4 MB. Jika Anda menjalankan dengan memori terbatas (misalnya, di lingkungan J2ME (Platform Java 2, Edisi Mikro)), atau bandwidth sangat tinggi (misalnya, dalam applet), menggunakan parser besar tersebut mungkin bukan solusi yang layak .

Ukuran besar library tersebut sebagian karena memiliki banyak fungsi — mungkin lebih dari yang Anda butuhkan. Mereka memvalidasi XML DTD (definisi tipe dokumen), kemungkinan skema, dan banyak lagi. Namun, Anda mungkin sudah tahu bahwa aplikasi Anda akan menerima XML yang valid. Selain itu, Anda mungkin sudah memutuskan bahwa Anda hanya menginginkan rangkaian karakter UTF-8. Oleh karena itu, Anda benar-benar menginginkan pemrosesan elemen XML berbasis peristiwa dan terjemahan entitas XML standar — Anda menginginkan parser yang tidak memvalidasi.

Catatan: Anda dapat mengunduh kode sumber artikel ini di Sumber.

Mengapa tidak menggunakan SAX saja?

Anda dapat mengimplementasikan antarmuka SAX (Simple API for XML) dengan fungsionalitas terbatas, melontarkan pengecualian yang dinamai NotImplementedsaat Anda menemukan sesuatu yang tidak perlu.

Tidak diragukan lagi, Anda dapat mengembangkan sesuatu yang jauh lebih kecil dari jaxp.jar/parser.jarperpustakaan 1,4 MB . Namun sebaliknya, Anda dapat lebih mengurangi ukuran kode dengan menentukan kelas Anda sendiri. Faktanya, paket yang kami buat di sini akan jauh lebih kecil daripada file jar yang berisi definisi antarmuka SAX.

Parser cepat dan kotor kami berbasis peristiwa seperti parser SAX. Juga seperti parser SAX, ini memungkinkan Anda menerapkan antarmuka untuk menangkap dan memproses peristiwa yang sesuai dengan atribut dan tag elemen awal / akhir. Semoga Anda yang pernah menggunakan SAX akan mengenal parser ini.

Batasi fungsionalitas XML

Banyak orang menginginkan format data tekstual XML yang sederhana dan dapat mendeskripsikan diri sendiri. Mereka ingin dengan mudah memilih elemen, atribut dan nilainya, dan konten tekstual elemen. Dengan mengingat hal itu, mari pertimbangkan fungsi apa yang perlu kita pertahankan.

Paket penguraian sederhana kami hanya memiliki satu kelas QDParser,, dan satu antarmuka DocHandler,. Itu QDParsersendiri memiliki satu metode statis publik parse(DocHandler,Reader), yang akan kami terapkan sebagai mesin negara hingga.

Pengurai fungsionalitas terbatas kami memperlakukan DTD dan instruksi pemrosesan hanya sebagai komentar, jadi tidak akan bingung dengan keberadaan atau penggunaan kontennya.

Karena kami tidak akan memproses DOCTYPE, parser kami tidak dapat membaca definisi entitas kustom. Kami hanya akan memiliki yang standar yang tersedia: &, <,>, ', dan ". Jika ini merupakan masalah, Anda dapat memasukkan kode untuk memperluas definisi kustom, seperti yang ditunjukkan kode sumber. Atau, Anda dapat memproses dokumen — mengganti definisi entitas kustom dengan teks yang diperluas sebelum menyerahkan dokumen ke QDParser.

Parser kami juga tidak dapat mendukung bagian bersyarat; misalnya, atau . Tanpa kemampuan untuk menentukan definisi entitas kustom di DOCTYPE, kami tidak benar-benar membutuhkan fungsionalitas ini. Kami dapat memproses bagian tersebut, jika ada, sebelum data dikirim ke aplikasi ruang terbatas kami.

Karena kami tidak akan memproses deklarasi atribut apa pun, spesifikasi XML mengharuskan kami mempertimbangkan semua jenis atribut menjadi CDATA. Jadi, kita cukup menggunakan java.util.Hashtablealih-alih org.xml.sax.AttributeListmenyimpan daftar atribut elemen. Kami hanya memiliki informasi nama / nilai untuk digunakan Hashtable, tetapi kami tidak memerlukan getType()metode karena tetap akan selalu kembali CDATA.

Kurangnya deklarasi atribut memiliki konsekuensi lain juga. Misalnya, parser tidak akan memberikan nilai atribut default. Selain itu, kami tidak dapat secara otomatis mengurangi ruang kosong menggunakan NMTOKENSdeklarasi. Namun, kami dapat menangani kedua masalah tersebut saat menyiapkan dokumen XML kami, sehingga pemrograman tambahan dapat dikecualikan dari aplikasi menggunakan parser.

Faktanya, semua fungsionalitas yang hilang dapat dikompensasikan dengan menyiapkan dokumen secara tepat. Anda dapat memindahkan semua pekerjaan yang terkait dengan fitur yang hilang (jika Anda menginginkannya) dari pengurai cepat dan kotor ke langkah persiapan dokumen.

Fungsionalitas pengurai

Cukup tentang apa yang tidak bisa dilakukan parser. Apa yang bisa dilakukannya?

  • Ini mengenali semua tag awal dan tag akhir elemen
  • Ini mencantumkan atribut, di mana nilai atribut dapat diapit dalam tanda kutip tunggal atau ganda
  • Itu mengenali konstruksi
  • Ini mengenali entitas standar: &, <,>, ", dan ', serta entitas numerik
  • Ini memetakan garis yang diakhiri dengan \r\ndan \rke \ninput, sesuai dengan Spesifikasi XML, Bagian 2.11

Pengurai hanya melakukan pemeriksaan kesalahan minimal dan menampilkan Exceptionjika menemui sintaks yang tidak diharapkan, seperti entitas yang tidak diketahui. Namun, sekali lagi, parser ini tidak memvalidasi; itu mengasumsikan dokumen XML yang diterimanya valid.

Cara menggunakan paket ini

Menggunakan parser XML quick-and-dirty itu sederhana. Pertama, terapkan DocHandlerantarmuka. Kemudian, parse dengan mudah file bernama config.xml:

DocHandler doc = new MyDocHandler (); QDParser.parse (doc, FileReader baru ("config.xml"));

Kode sumber mencakup dua contoh yang menyediakan DocHandlerimplementasi lengkap . Yang pertama DocHandler, dipanggil Reporter, hanya melaporkan semua peristiwa System.outsaat membacanya. Anda bisa menguji Reporterdengan contoh file XML ( config.xml).

Contoh kedua dan yang lebih kompleks Conf,, memperbarui bidang pada struktur data yang ada yang berada dalam memori. Confmenggunakan java.lang.reflectpaket untuk menemukan bidang dan objek yang dijelaskan di config.xml. Jika Anda menjalankan program ini, ini akan mencetak informasi diagnostik yang memberi tahu Anda objek apa yang diperbarui dan bagaimana caranya. Ini mencetak pesan kesalahan jika file konfigurasi memintanya untuk memperbarui bidang yang tidak ada.

Ubah paket ini

Anda mungkin ingin mengubah paket ini untuk aplikasi Anda sendiri. Anda dapat menambahkan definisi entitas kustom — baris 180 di QDParser.javaberisi komentar "Sisipkan definisi entitas kustom di sini".

Anda juga dapat menambah fungsionalitas mesin keadaan terbatas, memulihkan fungsionalitas yang telah saya kecualikan di sini. Jika demikian, ukuran kode sumber yang kecil akan membuat tugas ini relatif mudah.

Jaga agar tetap kecil

The QDParserkelas menempati sekitar 3 KB setelah Anda mengkompilasi dan berkemas ke file jar. Kode sumber itu sendiri, dengan komentar, lebih dari 300 baris. Ini harus cukup kecil untuk sebagian besar aplikasi dengan ruang terbatas, dan mempertahankan spesifikasi XML yang cukup untuk menikmati sebagian besar fitur yang berguna.

Steven Brandt memiliki gelar PhD di bidang astrofisika komputasi dan merupakan pemilik Stevesoft, perusahaan yang menjual perangkat lunak ekspresi reguler untuk Java.

Pelajari lebih lanjut tentang topik ini

  • Kode sumber untuk tip ini

    //images.techhive.com/downloads/idge/imported/article/jvw/2002/05/xmlparsertip.zip

  • Spesifikasi XML di W3C

    //www.w3.org/TR/2000/REC-xml-20001006

  • Situs SAX

    //sax.sourceforge.net

  • Situs JAXP

    //java.sun.com/xml/jaxp/index.html

  • Situs J2ME

    //java.sun.com/j2me/

  • Jelajahi bagian Java dan XML dari Indeks Topikal JavaWorld

    //www.javaworld.com/channel_content/jw-xml-index.shtml

  • Lihat semua Tips Java sebelumnya dan kirimkan Tips Anda sendiri

    //www.javaworld.com/javatips/jw-javatips.index.html

  • Belajar Java dari bawah ke atas di JavaWorld' s Java 101 kolom

    //www.javaworld.com/javaworld/topicalindex/jw-ti-java101.html

  • Java ahli menjawab pertanyaan Java terberat Anda di JavaWorld' s Java Q & A kolom

    //www.javaworld.com/javaworld/javaqa/javaqa-index.html

  • Jelajahi bagian Core Java dari Indeks Topikal JavaWorld

    //www.javaworld.com/channel_content/jw-core-index.shtml

  • Ikuti terus Trik Tip 'N kami dengan berlangganan buletin email mingguan gratis JavaWorld

    //www.javaworld.com/subscribe

  • Pelajari dasar-dasar client-side Java di JavaWorld' s Java Pemula diskusi. Topik inti mencakup bahasa Java, Mesin Virtual Java, API, dan alat pengembangan

    //forums.idg.net/[email protected]@.ee6b804

  • Anda akan menemukan banyak artikel terkait TI dari publikasi saudara kita di .net

Artikel ini, "Tip Java 128: Membuat parser XML yang cepat dan kotor" awalnya diterbitkan oleh JavaWorld.