Saya memiliki String Java yang berisi XML, tanpa umpan baris atau lekukan. Saya ingin mengubahnya menjadi sebuah String dengan XML yang diformat dengan baik. Bagaimana saya melakukan ini?
String unformattedXml = "<tag><nested>hello</nested></tag>";
String formattedXml = new [UnknownClass]().format(unformattedXml);
Catatan: Input saya adalah sebuah String . Output saya adalah sebuah String .
(Dasar) hasil tiruan:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<tag>
<nested>hello</nested>
</tag>
</root>
java
xml
pretty-print
Steve McLeod
sumber
sumber
Jawaban:
Catatan: Hasil dapat bervariasi tergantung pada versi Java. Cari solusi untuk platform Anda.
sumber
<?xml version="1.0" encoding="UTF-8"?>
?<?xml ...>
deklarasi, tambahkantransformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes")
doc
didefinisikan?Inilah jawaban untuk pertanyaan saya sendiri. Saya menggabungkan jawaban dari berbagai hasil untuk menulis kelas yang cukup mencetak XML.
Tidak ada jaminan tentang responsnya dengan XML atau dokumen besar yang tidak valid.
sumber
writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
setelahLSSerializer writer = ...
baris.document
diinisialisasi, jadi saya pikir saya mungkin menambahkan deselerasi dan membuat contoh cepat dari itu. Beri tahu saya jika saya harus mengubah sesuatu, pastebin.com/XL7932aCsolusi yang lebih sederhana berdasarkan jawaban ini :
Kasus cobaan:
pengembalian:
sumber
factory.setAttribute("indent-number", 4);
dan sekarang berfungsi.<?xml version="1.0" encoding="UTF-8"?>
?transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
<?xml version="1.0" encoding="UTF-8"?><root>
semua dalam satu baris. Ada ide mengapa?transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes");
bekerja untuk saya.Sekarang ini tahun 2012 dan Java dapat melakukan lebih banyak daripada biasanya dengan XML, saya ingin menambahkan alternatif untuk jawaban yang saya terima. Ini tidak memiliki dependensi di luar Java 6.
sumber
Hanya untuk mencatat bahwa jawaban berperingkat teratas membutuhkan penggunaan xerces.
Jika Anda tidak ingin menambahkan ketergantungan eksternal ini maka Anda cukup menggunakan pustaka jdk standar (yang sebenarnya dibangun menggunakan xerces secara internal).
NB Ada bug dengan versi jdk 1.5 lihat http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6296446 tetapi sudah diatasi sekarang.,
(Perhatikan jika terjadi kesalahan ini akan mengembalikan teks asli)
sumber
Aku sudah cukup dicetak di masa lalu menggunakan org.dom4j.io.OutputFormat.createPrettyPrint () metode
sumber
prettyPrintedString.replaceAll("\\s+\n", "\n")
Berikut cara melakukannya menggunakan dom4j :
Impor:
Kode:
sumber
<?xml version...
pada satu baris dan semua lainnya pada baris lain.Karena Anda mulai dengan a
String
, Anda perlu menyamarkan suatuDOM
objek (mis.Node
) Sebelum Anda dapat menggunakanTransformer
. Namun, jika Anda tahu string XML Anda valid, dan Anda tidak ingin mengeluarkan overhead memori dari penguraian string ke DOM, kemudian jalankan transformasi di atas DOM untuk mendapatkan string kembali - Anda bisa melakukan beberapa cara lama karakter dengan karakter parsing. Masukkan baris dan spasi baru setelah setiap</...>
karakter, pertahankan dan indentasi penghitung (untuk menentukan jumlah spasi) yang Anda tambahkan untuk setiap<...>
dan pengurangan untuk setiap yang</...>
Anda lihat.Penafian - Saya melakukan edit cut / paste / teks dari fungsi-fungsi di bawah ini, sehingga mereka tidak dapat dikompilasi seperti apa adanya.
sumber
Jika menggunakan pustaka XML pihak ke-3 ok, Anda bisa lolos dengan sesuatu yang secara signifikan lebih sederhana daripada yang disarankan oleh jawaban terpilih saat ini .
Dinyatakan bahwa input dan output haruslah Strings, jadi inilah metode utilitas yang melakukan hal itu, diimplementasikan dengan pustaka XOM :
Saya menguji apakah itu berhasil, dan hasilnya tidak bergantung pada versi JRE Anda atau yang seperti itu. Untuk melihat bagaimana menyesuaikan format output sesuai keinginan Anda, lihat
Serializer
API.Ini sebenarnya keluar lebih lama dari yang saya kira - beberapa baris tambahan diperlukan karena
Serializer
inginOutputStream
menulis. Tetapi perhatikan bahwa ada sangat sedikit kode untuk twiddling XML aktual di sini.(Jawaban ini adalah bagian dari evaluasi XOM saya, yang disarankan sebagai salah satu opsi dalam pertanyaan saya tentang perpustakaan XML Java terbaik untuk menggantikan dom4j. Sebagai catatan, dengan dom4j Anda dapat mencapai ini dengan mudah menggunakan
XMLWriter
danOutputFormat
. Edit : .. .sebagai ditunjukkan dalam jawaban mlo55 .)sumber
Kevin Hakanson berkata: "Namun, jika Anda tahu string XML Anda valid, dan Anda tidak ingin mengeluarkan memori dari penguraian string ke DOM, kemudian jalankan transformasi di atas DOM untuk mendapatkan string kembali - Anda bisa cukup lakukan beberapa karakter kuno dengan penguraian karakter. Sisipkan baris dan spasi baru setelah setiap karakter, simpan dan indentasi penghitung (untuk menentukan jumlah spasi) yang Anda tambahkan untuk setiap <...> dan pengurangan untuk setiap yang Anda lihat. "
Sepakat. Pendekatan semacam itu jauh lebih cepat dan memiliki ketergantungan yang jauh lebih sedikit.
Contoh solusi:
sumber
Hmmm ... menghadapi sesuatu seperti ini dan ini adalah bug yang dikenal ... cukup tambahkan OutputProperty ini ..
Semoga ini membantu ...
sumber
Mengenai komentar bahwa "Anda harus terlebih dahulu membangun pohon DOM": Tidak, Anda tidak perlu dan tidak boleh melakukannya.
Sebagai gantinya, buat StreamSource (new StreamSource (new StringReader (str)), dan masukkan itu ke transformator identitas yang disebutkan. Itu akan menggunakan parser SAX, dan hasilnya akan jauh lebih cepat. Membangun pohon perantara adalah overhead murni untuk kasus ini. Kalau tidak, jawaban berperingkat teratas itu baik.
sumber
Menggunakan scala:
Anda dapat melakukan ini di Jawa juga, jika Anda bergantung pada scala-library.jar. Ini terlihat seperti ini:
The
PrettyPrinter
objek dibangun dengan dua ints, yang menjadi pertama panjang garis max dan yang kedua menjadi langkah lekukan.sumber
versi yang sedikit ditingkatkan dari milosmns ...
sumber
} else if (row.startsWith("</")) {
bagian ini:else if (row.startsWith("</")) { String indent = repeatIdent(--stack); if (pretty.charAt(pretty.length() - 1) == '\n') { pretty.append(indent + row + "\n"); } else { pretty.append(row + "\n"); } }
Hanya untuk referensi di masa mendatang, inilah solusi yang sesuai untuk saya (terima kasih atas komentar yang @George Hawkins diposting di salah satu jawaban):
sumber
Jika Anda yakin memiliki XML yang valid, ini sederhana, dan menghindari pohon XML DOM. Mungkin memiliki beberapa bug, lakukan komentar jika Anda melihat sesuatu
sumber
Semua solusi di atas tidak bekerja untuk saya, maka saya menemukan ini http://myshittycode.com/2014/02/10/java-properly-indenting-xml-string/
Petunjuknya adalah menghapus spasi putih dengan XPath
sumber
Kode di bawah ini berfungsi dengan baik
sumber
Saya mencampur semuanya dan menulis satu program kecil. Itu membaca dari file xml dan mencetak. Just Alih-alih xzy berikan path file Anda.
sumber
Hanya solusi lain yang bekerja untuk kita
sumber
Menggunakan jdom2: http://www.jdom.org/
sumber
Sebagai alternatif dari jawaban dari max , codeskraps , David Easley dan milosmns , lihat perpustakaan printer saya yang ringan dan berkinerja tinggi: xml-formatter
Terkadang, seperti ketika menjalankan layanan SOAP yang diejek langsung dari file, ada baiknya memiliki printer-cantik yang juga menangani XML yang sudah tercetak:
Seperti yang dikomentari oleh beberapa orang, pencetakan cantik hanyalah cara menyajikan XML dalam bentuk yang lebih bisa dibaca manusia - spasi putih tidak termasuk dalam data XML Anda.
Perpustakaan ini dimaksudkan untuk pencetakan cantik untuk keperluan pencatatan, dan juga mencakup fungsi untuk memfilter (penghilangan subtree / anonimisasi) dan pencetakan XML dalam node CDATA dan Teks.
sumber
Saya memiliki masalah yang sama dan saya mengalami kesuksesan besar dengan JTidy ( http://jtidy.sourceforge.net/index.html )
Contoh:
sumber
Underscore-java memiliki metode statis
U.formatXml(string)
. Saya adalah pengelola proyek. Contoh langsungKeluaran:
sumber
ada utilitas xml baris perintah yang sangat bagus yang disebut xmlstarlet ( http://xmlstar.sourceforge.net/ ) yang dapat melakukan banyak hal yang banyak orang gunakan.
Anda dapat menjalankan program ini secara terprogram menggunakan Runtime.exec dan kemudian membaca file output yang diformat. Ini memiliki lebih banyak opsi dan pelaporan kesalahan yang lebih baik daripada beberapa baris kode Java dapat menyediakan.
unduh xmlstarlet: http://sourceforge.net/project/showfiles.php?group_id=66612&package_id=64589
sumber
Saya telah menemukan bahwa di Jawa 1.6.0_32 metode normal untuk cukup mencetak string XML (menggunakan Transformer dengan null atau identitas xslt) tidak berperilaku seperti yang saya inginkan jika tag hanya dipisahkan oleh spasi, bukan karena tidak memiliki pemisahan teks. Saya mencoba menggunakan
<xsl:strip-space elements="*"/>
dalam template saya tetapi tidak berhasil. Solusi paling sederhana yang saya temukan adalah menghapus ruang seperti yang saya inginkan menggunakan SAXSource dan filter XML. Karena solusi saya adalah untuk logging, saya juga memperluas ini untuk bekerja dengan fragmen XML yang tidak lengkap. Catatan metode normal tampaknya berfungsi dengan baik jika Anda menggunakan DOMSource tetapi saya tidak ingin menggunakan ini karena ketidaklengkapan dan overhead memori.sumber
Solusi yang saya temukan di sini untuk Java 1.6+ tidak memformat ulang kode jika sudah diformat. Yang bekerja untuk saya (dan memformat ulang kode yang sudah diformat) adalah sebagai berikut.
Ini adalah alat yang baik untuk digunakan dalam pengujian unit Anda untuk perbandingan xml string penuh.
sumber
Bagi mereka yang mencari solusi cepat dan kotor - yang tidak memerlukan XML 100% valid. mis. dalam kasus REST / SOAP logging (Anda tidak pernah tahu apa yang orang lain kirim ;-))
Saya menemukan dan menambahkan kode terpotong yang saya temukan online yang menurut saya masih hilang di sini sebagai pendekatan yang valid:
di sini adalah output:
sumber
Saya melihat satu jawaban menggunakan
Scala
, jadi inilah jawaban lainGroovy
, untuk berjaga-jaga seandainya seseorang menganggapnya menarik. Indentasi default adalah 2 langkah,XmlNodePrinter
konstruktor dapat melewati nilai lain juga.Penggunaan dari Jawa jika jar asyik di classpath
sumber
Jika Anda tidak perlu lekukan yang banyak tetapi beberapa jeda baris, itu bisa cukup untuk hanya regex ...
Kode ini bagus, bukan hasil karena lekukan yang hilang.
(Untuk solusi dengan indentasi, lihat jawaban lain.)
sumber