Cara terbaik untuk menyandikan data teks untuk XML di Java?

93

Sangat mirip dengan pertanyaan ini , kecuali untuk Java.

Apa cara yang direkomendasikan untuk mengenkode string untuk keluaran XML di Java. String tersebut mungkin berisi karakter seperti "&", "<", dll.

Epaga
sumber

Jawaban:

41

Sangat sederhana: gunakan pustaka XML. Dengan cara itu sebenarnya akan benar alih-alih membutuhkan pengetahuan rinci tentang bit dari spesifikasi XML.

Jon Skeet
sumber
25
Bisakah Anda merekomendasikan perpustakaan seperti itu? (Saya merasa mengejutkan bahwa ini bukan bagian standar dari Java edisi 5 ... tugas yang umum).
Tim Cooper
4
XML adalah bagian dari kerangka kerja Java standar - lihat di org.w3c.sax dan org.w3c.dom. Namun, ada beberapa kerangka kerja yang lebih mudah digunakan, seperti JDom. Perhatikan bahwa mungkin tidak ada metode "pengkodean string untuk keluaran XML" - Saya lebih merekomendasikan bahwa seluruh tugas XML harus dilakukan dengan perpustakaan daripada hanya melakukan bit pada satu waktu dengan manipulasi string.
Jon Skeet
1
Ini bukan saran yang berguna saat mengeluarkan XHTML - FlyingSaucer memerlukan XML, tetapi tidak mungkin saya membuat template melalui XML lib :). Untungnya StringTemplate memungkinkan saya untuk keluar dengan cepat dari semua objek String.
Stephen
4
@mice: Pertanyaannya diberi tag Java, dan Java memiliki banyak pustaka XML. Memang, ada API XML dipanggang ke Jawa, sehingga tidak akan ada perlu menambahkan apa-apa lagi ... tapi bahkan jika Anda melakukannya, beberapa ratus K jarang masalah di luar seluler hari ini. Bahkan jika itu bukan Java, saya akan sangat berhati-hati saat mengembangkan platform yang tidak memiliki API XML ...
Jon Skeet
2
@mice: DOM API sangat mampu menghasilkan XML. Atau ada perpustakaan pihak ketiga yang cukup kecil. (Misalnya, file jar JDom adalah 114K.) Menggunakan API XML masih merupakan cara yang disarankan untuk membuat XML.
Jon Skeet
124

Seperti yang telah disebutkan orang lain, menggunakan pustaka XML adalah cara termudah. Jika Anda memang ingin melarikan diri, Anda dapat melihat StringEscapeUtilsdari perpustakaan Apache Commons Lang .

Fabian Steeg
sumber
Ini bisa menjadi cara yang harus dilakukan jika Anda tidak peduli dengan ketepatan mutlak, misalnya jika Anda menyusun prototipe.
Chase Seibert
2
Gunakan StringEscapeUtils.escapeXml(str)dari commons-lang. Saya menggunakannya di aplikasi App Engine - bekerja dengan sangat baik. Berikut adalah Java Doc untuk fungsi ini:
Oleg K
Metode escapeXml dari StringEscapeUtils tampaknya agak mahal. Apakah ada metode yang lebih efisien yang beroperasi pada StringBuffer daripada String?
CKing
Apakah metode ini berfungsi untuk konten dan atribut XML? Bagi saya sepertinya itu tidak berfungsi untuk atribut. Sepertinya tidak melarikan diri \t, \ndan \r.
Lii
@Lii dan \t, \natau \rperlu di-escape?
Betlista
20

Gunakan saja.

<![CDATA[ your text here ]]>

Ini akan mengizinkan karakter apa pun kecuali akhiran

]]>

Jadi, Anda dapat menyertakan karakter yang ilegal seperti & dan>. Sebagai contoh.

<element><![CDATA[ characters such as & and > are allowed ]]></element>

Namun, atribut harus di-escape karena blok CDATA tidak dapat digunakan untuknya.

ng.
sumber
11
Dalam banyak kasus, bukan itu yang harus Anda lakukan. Terlalu banyak orang yang menyalahgunakan tag CDATA. Maksud dari CDATA adalah untuk memberi tahu prosesor agar tidak memprosesnya sebagai XML dan hanya meneruskannya. Jika Anda mencoba membuat file XML, Anda harus membuat XML, tidak hanya meneruskan byte melalui beberapa elemen pembungkus.
Mads Hansen
2
@Mads, menggunakan CDATA menghasilkan file XML yang valid sehingga sama baiknya dengan melakukannya dengan "cara yang benar". Jika Anda tidak menyukainya, parse setelah itu, ubah identitas, dan cetak.
Thorbjørn Ravn Andersen
24
Jika Anda membungkus teks dalam elemen CDATA, Anda harus keluar dari penanda penutup CDATA: "]]>" ... kecuali Anda tidak dapat menghindarinya. Jadi, sebagai gantinya Anda harus memecah kode Anda menjadi beberapa bagian di mana Anda meletakkan setengah dari data di satu elemen CDATA dan setengah lainnya di detik: <! [CDATA [Data ini berisi penanda penutup CDATA: "]]]]> <! [CDATA [> "itulah sebabnya ia harus dipecah.]]> ... Pada akhirnya, akan jauh lebih mudah untuk hanya menggunakan '<', '>' dan '&' sebagai gantinya. Tentu saja banyak aplikasi mengabaikan potensi masalah dengan penanda penutup CDATA dalam data. Kurasa ketidaktahuan adalah kebahagiaan. :)
Stijn de Witt
3
@StijndeWitt benar sekali. CDATA bukanlah obat mujarab untuk keluar dari karakter khusus.
dnault
Ini ide yang buruk. CDATA tidak mengizinkan karakter apa pun di luar pengkodean XML.
Florian F
14

Ini telah bekerja dengan baik bagi saya untuk memberikan versi escape dari string teks:

public class XMLHelper {

/**
 * Returns the string where all non-ascii and <, &, > are encoded as numeric entities. I.e. "&lt;A &amp; B &gt;"
 * .... (insert result here). The result is safe to include anywhere in a text field in an XML-string. If there was
 * no characters to protect, the original string is returned.
 * 
 * @param originalUnprotectedString
 *            original string which may contain characters either reserved in XML or with different representation
 *            in different encodings (like 8859-1 and UFT-8)
 * @return
 */
public static String protectSpecialCharacters(String originalUnprotectedString) {
    if (originalUnprotectedString == null) {
        return null;
    }
    boolean anyCharactersProtected = false;

    StringBuffer stringBuffer = new StringBuffer();
    for (int i = 0; i < originalUnprotectedString.length(); i++) {
        char ch = originalUnprotectedString.charAt(i);

        boolean controlCharacter = ch < 32;
        boolean unicodeButNotAscii = ch > 126;
        boolean characterWithSpecialMeaningInXML = ch == '<' || ch == '&' || ch == '>';

        if (characterWithSpecialMeaningInXML || unicodeButNotAscii || controlCharacter) {
            stringBuffer.append("&#" + (int) ch + ";");
            anyCharactersProtected = true;
        } else {
            stringBuffer.append(ch);
        }
    }
    if (anyCharactersProtected == false) {
        return originalUnprotectedString;
    }

    return stringBuffer.toString();
}

}
Thorbjørn Ravn Andersen
sumber
1
stringBuffer.append ("& #" + (int) ch + ";"); Ini tidak akan berfungsi untuk karakter multibyte. Saya mengalami ini sekarang dengan karakter emoji, urutan UTF8 F0 9F 98 8D.
Kylar
14

Coba ini:

String xmlEscapeText(String t) {
   StringBuilder sb = new StringBuilder();
   for(int i = 0; i < t.length(); i++){
      char c = t.charAt(i);
      switch(c){
      case '<': sb.append("&lt;"); break;
      case '>': sb.append("&gt;"); break;
      case '\"': sb.append("&quot;"); break;
      case '&': sb.append("&amp;"); break;
      case '\'': sb.append("&apos;"); break;
      default:
         if(c>0x7e) {
            sb.append("&#"+((int)c)+";");
         }else
            sb.append(c);
      }
   }
   return sb.toString();
}
Pointer Null
sumber
8
Anda punya setidaknya dua bug yang bisa saya lihat. Yang satu halus, yang lainnya tidak. Saya tidak akan mengalami bug seperti itu - karena saya tidak akan menemukan kembali kemudi sejak awal.
Jon Skeet
1
Dan melakukan iterasi melalui string Unicode sedikit lebih rumit. Lihat di sini: stackoverflow.com/q/1527856/402322
ceving
1
Tidak yakin itu halus tetapi Lebih baik mempertimbangkan kasus di mana t==null.
Myobis
1
@ user1003916: Pelolosan XML dirancang untuk mengubah & kejadian apa pun menjadi & amp; jadi begitulah cara kerjanya. Jika Anda mengecualikan string yang sudah lolos, itu salah Anda.
Pointer Null
3
Saya senang dengan versi finalnya. Java SE kompak, cepat, dan efisien. Melakukan apa yang perlu dilakukan daripada mengunduh bloatware 100 MB lainnya selalu lebih baik di buku saya.
Roger F. Gay
11

Pertanyaan ini sudah berusia delapan tahun dan masih belum merupakan jawaban yang sepenuhnya benar! Tidak, Anda tidak perlu mengimpor seluruh API pihak ketiga untuk melakukan tugas sederhana ini. Saran yang buruk.

Metode berikut akan:

  • menangani karakter di luar bidang multibahasa dasar dengan benar
  • karakter escape yang diperlukan dalam XML
  • escape setiap karakter non-ASCII, yang bersifat opsional tetapi umum
  • ganti karakter ilegal dalam XML 1.0 dengan karakter substitusi Unicode. Tidak ada pilihan terbaik di sini - menghapusnya sama validnya.

Saya telah mencoba mengoptimalkan untuk kasus yang paling umum, sambil tetap memastikan Anda dapat menyalurkan / dev / random melalui ini dan mendapatkan string yang valid dalam XML.

public static String encodeXML(CharSequence s) {
    StringBuilder sb = new StringBuilder();
    int len = s.length();
    for (int i=0;i<len;i++) {
        int c = s.charAt(i);
        if (c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
            c = ((c-0xd7c0)<<10) | (s.charAt(++i)&0x3ff);    // UTF16 decode
        }
        if (c < 0x80) {      // ASCII range: test most common case first
            if (c < 0x20 && (c != '\t' && c != '\r' && c != '\n')) {
                // Illegal XML character, even encoded. Skip or substitute
                sb.append("&#xfffd;");   // Unicode replacement character
            } else {
                switch(c) {
                  case '&':  sb.append("&amp;"); break;
                  case '>':  sb.append("&gt;"); break;
                  case '<':  sb.append("&lt;"); break;
                  // Uncomment next two if encoding for an XML attribute
//                  case '\''  sb.append("&apos;"); break;
//                  case '\"'  sb.append("&quot;"); break;
                  // Uncomment next three if you prefer, but not required
//                  case '\n'  sb.append("&#10;"); break;
//                  case '\r'  sb.append("&#13;"); break;
//                  case '\t'  sb.append("&#9;"); break;

                  default:   sb.append((char)c);
                }
            }
        } else if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) {
            // Illegal XML character, even encoded. Skip or substitute
            sb.append("&#xfffd;");   // Unicode replacement character
        } else {
            sb.append("&#x");
            sb.append(Integer.toHexString(c));
            sb.append(';');
        }
    }
    return sb.toString();
}

Sunting: bagi mereka yang terus bersikeras bahwa itu bodoh untuk menulis kode Anda sendiri untuk ini ketika ada Java API yang sangat bagus untuk menangani XML, Anda mungkin ingin tahu bahwa StAX API disertakan dengan Oracle Java 8 (saya belum menguji yang lain ) gagal untuk mengenkode konten CDATA dengan benar: tidak lolos]]> urutan dalam konten. Pustaka pihak ketiga, bahkan yang merupakan bagian dari inti Java, tidak selalu merupakan pilihan terbaik.

Mike B
sumber
1 untuk kode mandiri. Hanya membandingkan kode Anda dengan implementasi jambu biji , saya bertanya-tanya bagaimana dengan '\ t', '\ n', '\ r'? Lihat juga catatan di guava docs
jschnasse
2
Tidak perlu keluar \ n, \ r dan \ t, mereka valid, meskipun mereka membuat format agak jelek. Saya telah memodifikasi kode untuk menunjukkan bagaimana escsape mereka jika itu yang Anda inginkan.
Mike B
1
Tidak ada cara untuk "melarikan diri]]>" di CDATA.
kmkaplan
1
Maka itu harus menolak konten dengan melemparkan IllegalArgumentException. Dalam keadaan apa pun itu tidak boleh mengklaim berhasil tetapi masih mengeluarkan XML yang tidak valid.
Mike B
Alih-alih mengganti karakter ilegal di XML 1.0 dengan karakter substitusi Unicode, Anda dapat menggunakan metode saya di sini stackoverflow.com/a/59475093/3882565 .
stonar96
8

StringEscapeUtils.escapeXml()tidak lolos dari karakter kontrol (<0x20). XML 1.1 memungkinkan karakter kontrol; XML 1.0 tidak. Misalnya, XStream.toXML()dengan senang hati akan membuat serialisasi karakter kontrol objek Java ke dalam XML, yang akan ditolak oleh parser XML 1.0.

Untuk keluar dari karakter kontrol dengan Apache commons-lang, gunakan

NumericEntityEscaper.below(0x20).translate(StringEscapeUtils.escapeXml(str))
Steve Mitchell
sumber
7
public String escapeXml(String s) {
    return s.replaceAll("&", "&amp;").replaceAll(">", "&gt;").replaceAll("<", "&lt;").replaceAll("\"", "&quot;").replaceAll("'", "&apos;");
}
iCrazybest
sumber
5
Merangkai replaceAllpanggilan sangat tidak efisien, terutama untuk string besar. Setiap panggilan menghasilkan objek String baru yang dibuat, yang akan bertahan sampai sampah dikumpulkan. Juga, setiap panggilan membutuhkan pengulangan melalui string lagi. Ini dapat dikonsolidasikan ke dalam satu loop manual dengan perbandingan terhadap setiap karakter target di setiap iterasi.
daiscog
Ini harus menjadi jawaban yang diterima, meskipun tidak efisien. Ini memecahkan masalah dalam satu baris.
Stimpson Cat
Dan itu memiliki banyak bug. Lihat komentar ini di atas
David Balažic
Untuk memperbaiki bug ini, Anda juga dapat menggunakan metode saya di sini stackoverflow.com/a/59475093/3882565 . Perhatikan bahwa ini bukan pengganti tetapi dapat digunakan sebagai tambahan.
stonar96
6

Sementara idealisme mengatakan menggunakan perpustakaan XML, IMHO jika Anda memiliki ide dasar tentang XML maka akal sehat dan kinerja mengatakan templat itu sepenuhnya. Ini bisa dibilang lebih mudah dibaca juga. Meskipun menggunakan rutinitas melarikan diri dari perpustakaan mungkin adalah ide yang bagus.

Pertimbangkan ini: XML dulu dimaksudkan untuk ditulis oleh manusia.

Gunakan pustaka untuk menghasilkan XML saat menjadikan XML Anda sebagai "objek" yang lebih baik dalam membuat model masalah Anda. Misalnya, jika modul yang dapat dicolok berpartisipasi dalam proses pembuatan XML ini.

Sunting: tentang bagaimana benar-benar melarikan diri dari XML dalam template, penggunaan CDATA atau escapeXml(string)dari JSTL adalah dua solusi yang baik, escapeXml(string)dapat digunakan seperti ini:

<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>

<item>${fn:escapeXml(value)}</item>
Amr Mostafa
sumber
6

Perilaku StringEscapeUtils.escapeXml () telah berubah dari Commons Lang 2.5 menjadi 3.0. Sekarang tidak lagi lolos dari karakter Unicode yang lebih besar dari 0x7f.

Ini adalah hal yang baik, metode lama akan sedikit bersemangat untuk keluar dari entitas yang baru saja disisipkan ke dalam dokumen utf8.

Escaper baru yang akan disertakan dalam Google Guava 11.0 juga tampak menjanjikan: http://code.google.com/p/guava-libraries/issues/detail?id=799

Jasper Krijgsman
sumber
1
Berikut escaper XML Guava: code.google.com/p/guava-libraries/source/browse/guava/src/com/… . Secara umum, saya telah menemukan Guava menjadi arsitek yang lebih baik daripada Apache Commons.
jhclark
6

Bagi mereka yang mencari solusi tercepat untuk menulis: gunakan metode dari apache commons-lang :

Ingatlah untuk memasukkan ketergantungan:

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.5</version> <!--check current version! -->
</dependency>
Dariusz
sumber
5

Catatan: Pertanyaan Anda adalah tentang pelolosan , bukan penyandiaksaraan . Melarikan diri menggunakan <, dll. Untuk memungkinkan pengurai membedakan antara "ini adalah perintah XML" dan "ini adalah beberapa teks". Enkode adalah hal-hal yang Anda tentukan di header XML (UTF-8, ISO-8859-1, dll).

Pertama-tama, seperti yang orang lain katakan, gunakan perpustakaan XML. XML terlihat sederhana tetapi encoding + escaping adalah voodoo gelap (yang akan Anda lihat segera setelah Anda menemukan umlaut dan bahasa Jepang dan hal-hal aneh lainnya seperti " digit lebar penuh " (& # FF11; adalah 1)). Menjaga agar XML dapat dibaca manusia adalah tugas Sisyphus.

Saya menyarankan untuk tidak pernah mencoba menjadi pintar tentang pengkodean teks dan melarikan diri dalam XML. Tetapi jangan biarkan hal itu menghentikan Anda untuk mencoba; ingatlah kapan itu menggigit Anda (dan itu akan terjadi).

Karena itu, jika Anda hanya menggunakan UTF-8, agar lebih mudah dibaca, Anda dapat mempertimbangkan strategi ini:

  • Jika teks memang berisi '<', '>' atau '&', bungkuslah <![CDATA[ ... ]]>
  • Jika teks tidak berisi ketiga karakter ini, jangan bengkokkan.

Saya menggunakan ini di editor SQL dan memungkinkan pengembang untuk memotong & menempelkan SQL dari alat SQL pihak ketiga ke XML tanpa khawatir akan kabur. Ini berfungsi karena SQL tidak dapat berisi umlaut dalam kasus kami, jadi saya aman.

Aaron Digulla
sumber
5

Meskipun pada prinsipnya saya setuju dengan Jon Skeet, terkadang saya tidak memiliki opsi untuk menggunakan pustaka XML eksternal. Dan saya merasa aneh dua fungsi untuk melarikan diri / unescape nilai sederhana (atribut atau tag, bukan dokumen lengkap) tidak tersedia di pustaka XML standar yang disertakan dengan Java.

Akibatnya dan berdasarkan jawaban berbeda yang saya lihat diposting di sini dan di tempat lain, berikut adalah solusi yang akhirnya saya buat (tidak ada yang berfungsi sebagai salin / tempel sederhana):

  public final static String ESCAPE_CHARS = "<>&\"\'";
  public final static List<String> ESCAPE_STRINGS = Collections.unmodifiableList(Arrays.asList(new String[] {
      "&lt;"
    , "&gt;"
    , "&amp;"
    , "&quot;"
    , "&apos;"
  }));

  private static String UNICODE_NULL = "" + ((char)0x00); //null
  private static String UNICODE_LOW =  "" + ((char)0x20); //space
  private static String UNICODE_HIGH = "" + ((char)0x7f);

  //should only be used for the content of an attribute or tag      
  public static String toEscaped(String content) {
    String result = content;
    
    if ((content != null) && (content.length() > 0)) {
      boolean modified = false;
      StringBuilder stringBuilder = new StringBuilder(content.length());
      for (int i = 0, count = content.length(); i < count; ++i) {
        String character = content.substring(i, i + 1);
        int pos = ESCAPE_CHARS.indexOf(character);
        if (pos > -1) {
          stringBuilder.append(ESCAPE_STRINGS.get(pos));
          modified = true;
        }
        else {
          if (    (character.compareTo(UNICODE_LOW) > -1)
               && (character.compareTo(UNICODE_HIGH) < 1)
             ) {
            stringBuilder.append(character);
          }
          else {
            //Per URL reference below, Unicode null character is always restricted from XML
            //URL: https://en.wikipedia.org/wiki/Valid_characters_in_XML
            if (character.compareTo(UNICODE_NULL) != 0) {
              stringBuilder.append("&#" + ((int)character.charAt(0)) + ";");
            }
            modified = true;
          }
        }
      }
      if (modified) {
        result = stringBuilder.toString();
      }
    }
    
    return result;
  }

Hal di atas mengakomodasi beberapa hal berbeda:

  1. hindari penggunaan logika berbasis char sampai benar-benar harus - meningkatkan kompatibilitas unicode
  2. upaya untuk menjadi seefisien mungkin mengingat probabilitasnya adalah kondisi "jika" kedua kemungkinan merupakan jalur yang paling banyak digunakan
  3. adalah fungsi murni; yaitu aman untuk benang
  4. mengoptimalkan dengan baik dengan pengumpul sampah dengan hanya mengembalikan konten StringBuilder jika sesuatu benar-benar berubah - jika tidak, string asli dikembalikan

Pada titik tertentu, saya akan menulis inversi fungsi ini, toUnescaped (). Saya hanya tidak punya waktu untuk melakukan itu hari ini. Ketika saya melakukannya, saya akan memperbarui jawaban ini dengan kode. :)

chaotic3quilibrium
sumber
Terlihat cukup bagus bagiku. Saya tidak ingin menambahkan toples lain ke proyek saya hanya untuk satu metode. Jika Anda memberi izin, bolehkah saya menyalin dan menempelkan kode Anda di milik saya?
RuntimeException
1
@SatishMotwani Tentu saja Anda dapat mengambil kode di atas dan melakukannya sesuka Anda. Menurut pemahaman saya bahwa kode apa pun yang diterbitkan di StackOverflow diasumsikan bebas hak cipta (tidak tercakup sebagai karya secara total). Di sisi lain, akan sangat sulit bagi seseorang untuk mengajukan klaim hak cipta apa pun dan mengharapkan hasil untuk dirinya sendiri.
chaotic3quilibrium
1
Terima kasih telah mengizinkan :-) Saya akan menggunakannya.
RuntimeException
Anda lupa menangani karakter NUL. Dan mungkin hal-hal lain juga.
David Balažic
@ DavidBalažic Oke, tolong jelaskan lebih detail apa yang mungkin saya lewatkan? Harap baca kode lebih dekat. Saya menangani SETIAP karakter Unicode TUNGGAL (dari 1.111.998), termasuk nullkarakternya. Bisakah Anda menjelaskan definisi kedua nilai, UNICODE_LOWdan UNICODE_HIGH? Harap baca ulang ifyang menggunakan dua nilai tersebut. Perhatikan null( \u0000yang mana (int)0) tidak berada di antara kedua nilai ini. Bacalah bagaimana itu menjadi "lolos" dengan benar seperti SEMUA karakter Unicode yang ada di luar rentang UNICODE_LOWdan UNICODE_HIGH, dengan menggunakan &#teknik ini.
chaotic3quilibrium
3

Untuk menghindari karakter XML, cara termudah adalah dengan menggunakan proyek Apache Commons Lang, JAR dapat diunduh dari: http://commons.apache.org/lang/

Kelasnya adalah ini: org.apache.commons.lang3.StringEscapeUtils;

Ini memiliki metode bernama "escapeXml", yang akan mengembalikan String yang di-escape dengan tepat.

Greg Burdett
sumber
Pembaruan: escapeXml sekarang tidak digunakan lagi - gunakan escapeXml10. Ref commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/…
Daniel
3

Jika Anda mencari perpustakaan untuk menyelesaikan pekerjaan, coba:

  1. Jambu biji 26.0 didokumentasikan di sini

    return XmlEscapers.xmlContentEscaper().escape(text);

    Catatan: Ada juga file xmlAttributeEscaper()

  2. Apache Commons Text 1.4 didokumentasikan di sini

    StringEscapeUtils.escapeXml11(text)

    Catatan: Ada juga escapeXml10()metode

jschnasse.dll
sumber
1

Berikut adalah solusi yang mudah dan bagus untuk mengenkode karakter beraksen juga!

String in = "Hi Lârry & Môe!";

StringBuilder out = new StringBuilder();
for(int i = 0; i < in.length(); i++) {
    char c = in.charAt(i);
    if(c < 31 || c > 126 || "<>\"'\\&".indexOf(c) >= 0) {
        out.append("&#" + (int) c + ";");
    } else {
        out.append(c);
    }
}

System.out.printf("%s%n", out);

Keluaran

Hi L&#226;rry &#38; M&#244;e!
Mike
sumber
Bukankah seharusnya "31" di baris pertama dari "jika" menjadi "32"; yaitu kurang dari karakter spasi? Dan jika "31" harus tetap ada, maka bukankah seharusnya itu diperbaiki menjadi "if (c <= 31 || ..." (tanda sama dengan tambahan setelah tanda kurang dari)?
chaotic3quilibrium
1

Ganti saja

 & with &amp;

Dan untuk karakter lain:

> with &gt;
< with &lt;
\" with &quot;
' with &apos;
raman rayat
sumber
0

Gunakan JAXP dan lupakan tentang penanganan teks, itu akan dilakukan untuk Anda secara otomatis.

Fernando Miguélez
sumber
Tautan Anda dalam bahasa Spanyol, yang tidak begitu berguna bagi kebanyakan dari kita. Lebih baik yang ini .
Vivit
0

Cobalah untuk menyandikan XML menggunakan Apache XML serializer

//Serialize DOM
OutputFormat format    = new OutputFormat (doc); 
// as a String
StringWriter stringOut = new StringWriter ();    
XMLSerializer serial   = new XMLSerializer (stringOut, 
                                          format);
serial.serialize(doc);
// Display the XML
System.out.println(stringOut.toString());
K Victor Rajan
sumber
0

Inilah yang saya temukan setelah mencari di mana-mana mencari solusi:

Dapatkan perpustakaan Jsoup:

<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.12.1</version>
</dependency>

Kemudian:

import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Entities
import org.jsoup.parser.Parser

String xml = '''<?xml version = "1.0"?>
<SOAP-ENV:Envelope
   xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope"
   SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding">

   <SOAP-ENV:Body xmlns:m = "http://www.example.org/quotations">
      <m:GetQuotation>
         <m:QuotationsName> MiscroSoft@G>>gle.com </m:QuotationsName>
      </m:GetQuotation>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>'''



Document doc = Jsoup.parse(new ByteArrayInputStream(xml.getBytes("UTF-8")), "UTF-8", "", Parser.xmlParser())
doc.outputSettings().charset("UTF-8")
doc.outputSettings().escapeMode(Entities.EscapeMode.base)

println doc.toString()

Semoga ini bisa membantu seseorang

wizston
sumber