Saya mencoba untuk menulis tes otomatis aplikasi yang pada dasarnya menerjemahkan format pesan khusus menjadi pesan XML dan mengirimkannya ke ujung lainnya. Saya punya pasangan input / output pesan yang baik sehingga yang perlu saya lakukan hanyalah mengirim pesan input dan mendengarkan pesan XML untuk keluar dari ujung lainnya.
Ketika tiba saatnya untuk membandingkan output aktual dengan output yang diharapkan, saya mengalami beberapa masalah. Pikiran pertama saya adalah hanya melakukan perbandingan string pada pesan yang diharapkan dan aktual. Ini tidak berfungsi dengan baik karena contoh data yang kami miliki tidak selalu diformat secara konsisten dan sering ada alias berbeda yang digunakan untuk ruang nama XML (dan terkadang ruang nama tidak digunakan sama sekali.)
Saya tahu saya dapat mengurai kedua string dan kemudian berjalan melalui masing-masing elemen dan membandingkannya sendiri dan ini tidak akan terlalu sulit untuk dilakukan, tetapi saya merasa ada cara yang lebih baik atau perpustakaan yang bisa saya manfaatkan.
Jadi, lanjut, pertanyaannya adalah:
Diberikan dua String Java yang keduanya mengandung XML yang valid, bagaimana Anda menentukan apakah keduanya setara secara semantik? Poin bonus jika Anda memiliki cara untuk menentukan apa perbedaannya.
Berikut ini akan memeriksa apakah dokumen sama menggunakan perpustakaan JDK standar.
menormalkan () apakah ada untuk memastikan tidak ada siklus (secara teknis tidak akan ada)
Kode di atas akan membutuhkan ruang putih untuk menjadi sama di dalam elemen, karena mempertahankan dan mengevaluasinya. Parser XML standar yang datang dengan Java tidak memungkinkan Anda untuk mengatur fitur untuk menyediakan versi kanonik atau memahami
xml:space
jika itu akan menjadi masalah maka Anda mungkin memerlukan pengurai XML pengganti seperti xerces atau menggunakan JDOM.sumber
setIgnoringElementContentWhitespace(false)
Xom memiliki utilitas Canonicalizer yang mengubah DOM Anda menjadi bentuk biasa, yang kemudian dapat Anda tegangkan dan bandingkan. Jadi, terlepas dari penyimpangan spasi putih atau pemesanan atribut, Anda bisa mendapatkan perbandingan dokumen Anda yang teratur dan dapat diprediksi.
Ini bekerja sangat baik di IDE yang telah mendedikasikan komparator String visual, seperti Eclipse. Anda mendapatkan representasi visual dari perbedaan semantik antara dokumen.
sumber
Versi terbaru dari XMLUnit dapat membantu pekerjaan menyatakan dua XML sama. Juga
XMLUnit.setIgnoreWhitespace()
danXMLUnit.setIgnoreAttributeOrder()
mungkin perlu untuk kasus tersebut.Lihat kode kerja dari contoh sederhana penggunaan Unit XML di bawah ini.
Jika menggunakan Maven, tambahkan ini ke
pom.xml
:sumber
Terima kasih, saya memperpanjang ini, coba ini ...
sumber
Membangun jawaban Tom , inilah contoh menggunakan XMLUnit v2.
Menggunakan dependensi pakar ini
..dan inilah kode tes
Dokumentasi yang menguraikan ini adalah https://github.com/xmlunit/xmlunit#comparing-two-documents
sumber
skaffman tampaknya memberikan jawaban yang bagus.
Cara lain mungkin untuk memformat XML menggunakan utilitas commmand line seperti xmlstarlet ( http://xmlstar.sourceforge.net/ ) dan kemudian memformat kedua string dan kemudian menggunakan utilitas utilitas (pustaka) apa pun (pustaka) untuk membedakan file output yang dihasilkan. Saya tidak tahu apakah ini solusi yang baik ketika masalah dengan ruang nama.
sumber
AssertJ 1.4+ memiliki pernyataan spesifik untuk membandingkan konten XML:
Ini Dokumentasi
sumber
Saya menggunakan Altova DiffDog yang memiliki opsi untuk membandingkan file XML secara struktural (mengabaikan data string).
Ini berarti bahwa (jika memeriksa opsi 'abaikan teks'):
dan
sama dalam arti bahwa mereka memiliki kesetaraan struktural. Ini berguna jika Anda memiliki contoh file yang berbeda dalam data, tetapi tidak terstruktur!
sumber
Ini akan membandingkan XML string lengkap (memformatnya kembali di jalan). Ini membuatnya mudah untuk bekerja dengan IDE Anda (IntelliJ, Eclipse), karena Anda cukup mengklik dan secara visual melihat perbedaan dalam file XML.
Saya lebih suka ini daripada XmlUnit karena kode klien (kode uji) lebih bersih.
sumber
Kode di bawah ini berfungsi untuk saya
sumber
Menggunakan JExamXML dengan aplikasi java
sumber
Saya membutuhkan fungsi yang sama seperti yang diminta dalam pertanyaan utama. Karena saya tidak diizinkan menggunakan pustaka pihak ketiga mana pun, saya telah membuat solusi sendiri berdasarkan pada solusi @Archimedes Trajano.
Berikut ini adalah solusi saya.
Ini membandingkan dua string XML dan menangani setiap pemetaan namespace yang tidak cocok dengan menerjemahkannya ke nilai unik di kedua string input.
Dapat diatur dengan baik yaitu dalam hal terjemahan ruang nama. Tetapi untuk persyaratan saya hanya melakukan pekerjaan.
sumber
Karena Anda mengatakan "setara secara semantik", saya berasumsi bahwa Anda ingin melakukan lebih dari sekadar memverifikasi bahwa output xml sama (string), dan Anda menginginkan sesuatu seperti
<foo> beberapa hal di sini </foo> </code>
dan
<foo> beberapa hal di sini </foo> </code>
baca sebagai setara. Pada akhirnya itu akan menjadi masalah bagaimana Anda mendefinisikan "setara semantik" pada objek apa pun yang Anda pesan. Cukup buat objek itu dari pesan dan gunakan custom equals () untuk menentukan apa yang Anda cari.
sumber