Beste Möglichkeit, Textdaten für XML in Java zu codieren?

93

Sehr ähnlich zu dieser Frage , außer Java.

Was ist die empfohlene Methode zum Codieren von Zeichenfolgen für eine XML-Ausgabe in Java? Die Zeichenfolgen können Zeichen wie "&", "<" usw. enthalten.

Epaga
quelle

Antworten:

40

Ganz einfach: Verwenden Sie eine XML-Bibliothek. Auf diese Weise ist es tatsächlich richtig, anstatt detaillierte Kenntnisse der Bits der XML-Spezifikation zu erfordern.

Jon Skeet
quelle
25
Können Sie eine solche Bibliothek empfehlen? (Ich finde es überraschend, dass dies kein Standardbestandteil von Java Edition 5 ist ... eine so häufige Aufgabe).
Tim Cooper
4
XML ist Teil des Standard-Java-Frameworks - siehe org.w3c.sax und org.w3c.dom. Es gibt jedoch auch einige benutzerfreundlichere Frameworks wie JDom. Beachten Sie, dass es möglicherweise keine Methode zum Codieren von Zeichenfolgen für die XML-Ausgabe gibt. Ich habe eher empfohlen, die gesamte XML-Aufgabe mit einer Bibliothek auszuführen, anstatt nur Bits gleichzeitig mit der Zeichenfolgenmanipulation auszuführen.
Jon Skeet
1
Dies ist kein so nützlicher Rat bei der Ausgabe von XHTML - FlyingSaucer erfordert XML, aber ich kann auf keinen Fall eine XML-Bibliothek erstellen :). Zum Glück kann ich mit StringTemplate schnell allen String-Objekten entkommen.
Stephen
4
@mice: Die Frage ist mit Java gekennzeichnet, und Java verfügt über viele XML-Bibliotheken. In der Tat gibt es XML-APIs, die in Java integriert sind, sodass Sie nichts weiter hinzufügen müssen ... aber selbst wenn Sie dies tun, sind einige hundert K heutzutage außerhalb von Mobilgeräten selten ein Problem. Selbst wenn es nicht Java wäre, wäre ich sehr vorsichtig bei der Entwicklung auf einer Plattform ohne XML-APIs ...
Jon Skeet
2
@mice: Die DOM-API kann perfekt XML generieren. Oder es gibt ziemlich kleine Bibliotheken von Drittanbietern. (Die JAR-Datei von JDom ist beispielsweise 114 KB groß.) Die Verwendung einer XML-API wird weiterhin als empfohlene Methode zum Erstellen von XML empfohlen.
Jon Skeet
123

Wie bereits erwähnt, ist die Verwendung einer XML-Bibliothek der einfachste Weg. Wenn Sie sich selbst entziehen möchten, können Sie in StringEscapeUtilsder Apache Commons Lang- Bibliothek nachsehen .

Fabian Steeg
quelle
Dies könnte der richtige Weg sein, wenn Sie sich nicht um absolute Korrektheit kümmern, beispielsweise wenn Sie einen Prototyp zusammenstellen.
Chase Seibert
2
Verwenden Sie StringEscapeUtils.escapeXml(str)von commons-lang. Ich benutze es in der App Engine-Anwendung - arbeite wie ein Zauber. Hier ist das Java-Dokument für diese Funktion:
Oleg K
Die EscapeXml-Methode von StringEscapeUtils scheint etwas kostspielig zu sein. Gibt es eine effizientere Methode, die einen StringBuffer anstelle eines Strings verarbeitet?
CKing
Funktioniert diese Methode sowohl für XML-Inhalte als auch für XML-Attribute? Mir scheint, dass es für Attribute nicht funktioniert. Es scheint nicht zu entkommen \t, \nund \r.
Lii
@Lii und \t, \noder \rmuss entkommen werden?
Betlista
20

Benutz einfach.

<![CDATA[ your text here ]]>

Dies erlaubt alle Zeichen außer dem Ende

]]>

Sie können also unzulässige Zeichen wie & und> einfügen. Beispielsweise.

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

Attribute müssen jedoch maskiert werden, da CDATA-Blöcke nicht für sie verwendet werden können.

ng.
quelle
11
In den meisten Fällen sollten Sie dies nicht tun. Zu viele Leute missbrauchen die CDATA-Tags. Die Absicht der CDATA ist es, den Prozessor anzuweisen, es nicht als XML zu verarbeiten und es einfach weiterzuleiten. Wenn Sie versuchen, eine XML-Datei zu erstellen, sollten Sie XML erstellen und nicht nur Bytes durch ein Wrapping-Element übergeben.
Mads Hansen
2
@Mads, die Verwendung von CDATA führt zu einer gültigen XML-Datei. Dies ist also genauso gut wie die "richtige Vorgehensweise". Wenn Sie es nicht mögen, analysieren Sie es anschließend, transformieren Sie es und drucken Sie es aus.
Thorbjørn Ravn Andersen
24
Wenn Sie Text in ein CDATA-Element einschließen, müssen Sie die CDATA-Schließmarkierung maskieren: "]]>" ... außer Sie können das nicht maskieren. Stattdessen müssen Sie Ihren Code in Teile zerlegen, in denen Sie die Hälfte der Daten in ein CDATA-Element und die andere Hälfte in eine Sekunde einfügen: <! [CDATA [Diese Daten enthalten eine CDATA-Schließmarkierung: "]]]> <! [CDATA [> "deshalb musste es aufgeteilt werden.]]> ... Am Ende kann es viel einfacher sein, stattdessen einfach '<', '>' und '&' zu entkommen. Natürlich ignorieren viele Apps das potenzielle Problem mit CDATA-Schließmarkierungen in den Daten. Unwissenheit ist Glückseligkeit, denke ich. :)
Stijn de Witt
3
@StijndeWitt ist absolut korrekt. CDATA ist kein Allheilmittel gegen Sonderzeichen.
dnault
Das ist eine schlechte Idee. CDATA erlaubt keine Zeichen außerhalb der XML-Codierung.
Florian F
14

Dies hat für mich gut funktioniert, um eine maskierte Version einer Textzeichenfolge bereitzustellen:

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
quelle
1
stringBuffer.append ("& #" + (int) ch + ";"); Dies funktioniert nicht für Multibyte-Zeichen. Ich stoße gerade mit einem Emoji-Zeichen darauf, der UTF8-Sequenz F0 9F 98 8D.
Kylar
14

Versuche dies:

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();
}
Zeiger Null
quelle
8
Sie haben mindestens zwei Fehler, die ich sehen kann. Einer ist subtil, der andere nicht. Ich hätte so einen Fehler nicht - weil ich das Rad überhaupt nicht neu erfinden würde.
Jon Skeet
1
Das Durchlaufen von Unicode-Zeichenfolgen ist etwas komplizierter. Siehe hier: stackoverflow.com/q/1527856/402322
ceving
1
Ich bin mir nicht sicher, ob es subtil ist, aber ich sollte besser den Fall betrachten, in dem t==null.
Myobis
1
@ user1003916: XML-Escapezeichen dient zum Konvertieren von & Vorkommen in & amp; so muss es also funktionieren. Wenn Sie bereits entkommene Zeichenfolge entfernen, ist das Ihre Schuld.
Zeiger Null
3
Ich bin mit der endgültigen Version zufrieden. Java SE ist kompakt, schnell und effizient. In meinem Buch ist es immer besser, genau das zu tun, was getan werden muss, anstatt weitere 100 MB Bloatware herunterzuladen.
Roger F. Gay
11

Diese Frage ist acht Jahre alt und immer noch keine völlig richtige Antwort! Nein, Sie sollten nicht eine vollständige API eines Drittanbieters importieren müssen, um diese einfache Aufgabe auszuführen. Schlechter Rat.

Die folgende Methode wird:

  • Behandeln Sie Zeichen außerhalb der mehrsprachigen Grundebene korrekt
  • In XML erforderliche Escapezeichen
  • Escapezeichen für Nicht-ASCII-Zeichen, was optional, aber häufig ist
  • Ersetzen Sie unzulässige Zeichen in XML 1.0 durch das Unicode-Ersetzungszeichen. Hier gibt es keine beste Option - das Entfernen ist genauso gültig.

Ich habe versucht, für den häufigsten Fall zu optimieren, während ich trotzdem sicherstellte, dass Sie dies durch / dev / random leiten und eine gültige Zeichenfolge in XML erhalten können.

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();
}

Bearbeiten: Für diejenigen, die weiterhin darauf bestehen, dass es dumm ist, Ihren eigenen Code dafür zu schreiben, wenn es perfekt gute Java-APIs für den Umgang mit XML gibt, möchten Sie vielleicht wissen, dass die StAX-API in Oracle Java 8 enthalten ist (andere habe ich nicht getestet ) codiert CDATA-Inhalte nicht korrekt: Es entgeht nicht]]> Sequenzen im Inhalt. Eine Drittanbieter-Bibliothek, auch eine, die Teil des Java-Kerns ist, ist nicht immer die beste Option.

Mike B.
quelle
+1 für Standalone-Code. Wenn ich nur Ihren Code mit der Guaven-Implementierung vergleiche , frage ich mich, was ist mit '\ t', '\ n', '\ r'? Siehe auch Notizen bei Guave Docs
Jschnasse
2
Es ist nicht nötig, \ n, \ r und \ t zu entkommen, sie sind gültig, obwohl sie die Formatierung etwas hässlich machen. Ich habe den Code geändert, um zu zeigen, wie man sie entführt, wenn Sie dies möchten.
Mike B
1
Es gibt keine Möglichkeit, in CDATA zu "entkommen]]>".
kmkaplan
1
Dann sollte der Inhalt durch Auslösen einer IllegalArgumentException abgelehnt werden. Unter keinen Umständen sollte es behaupten, erfolgreich zu sein, aber dennoch ungültiges XML ausgeben.
Mike B
Anstatt unzulässige Zeichen in XML 1.0 durch das Unicode-Ersetzungszeichen zu ersetzen, können Sie meine Methoden hier verwenden . Stackoverflow.com/a/59475093/3882565 .
stonar96
8

StringEscapeUtils.escapeXml()entgeht keinen Steuerzeichen (<0x20). XML 1.1 erlaubt Steuerzeichen; XML 1.0 nicht. Beispielsweise,XStream.toXML() werden die Steuerzeichen eines Java-Objekts gerne in XML serialisiert, was ein XML 1.0-Parser ablehnt.

Verwenden Sie, um Steuerzeichen mit Apache commons-lang zu umgehen

NumericEntityEscaper.below(0x20).translate(StringEscapeUtils.escapeXml(str))
Steve Mitchell
quelle
7
public String escapeXml(String s) {
    return s.replaceAll("&", "&amp;").replaceAll(">", "&gt;").replaceAll("<", "&lt;").replaceAll("\"", "&quot;").replaceAll("'", "&apos;");
}
iCrazybest
quelle
5
Das Verketten von replaceAllAnrufen ist sehr ineffizient, insbesondere bei großen Zeichenfolgen. Jeder Aufruf führt dazu, dass ein neues String-Objekt erstellt wird, das so lange herumhängt, bis der Müll gesammelt wird. Außerdem muss bei jedem Aufruf die Zeichenfolge erneut durchlaufen werden. Dies könnte in einer einzigen manuellen Schleife mit Vergleichen mit jedem Zielzeichen in jeder Iteration zusammengefasst werden.
Daiscog
Dies sollte die akzeptierte Antwort sein, auch wenn sie ineffizient ist. Es löst das Problem in einer einzigen Zeile.
Stimpson Cat
Und es hat viele Fehler. Siehe diesen Kommentar oben
David Balažic
Um diese Fehler zu beheben, können Sie hier zusätzlich meine Methode stackoverflow.com/a/59475093/3882565 verwenden . Beachten Sie, dass dies kein Ersatz ist, sondern zusätzlich verwendet werden kann.
stonar96
6

Während der Idealismus besagt, dass eine XML-Bibliothek verwendet werden soll, sagt IMHO, wenn Sie eine grundlegende Vorstellung von XML haben, der gesunde Menschenverstand und die Leistung sagen, dass die Vorlage vollständig ist. Es ist wohl auch besser lesbar. Die Verwendung der Escape-Routinen einer Bibliothek ist wahrscheinlich eine gute Idee.

Bedenken Sie: XML wurde von Menschen geschrieben werden soll.

Verwenden Sie Bibliotheken zum Generieren von XML, wenn Sie Ihr XML als "Objekt" haben, um Ihr Problem besser zu modellieren. Zum Beispiel, wenn steckbare Module am Prozess der Erstellung dieses XML beteiligt sind.

Bearbeiten: Wie man XML tatsächlich in Vorlagen maskiert, die Verwendung von CDATA oder escapeXml(string)von JSTL sind zwei gute Lösungen, escapeXml(string)die wie folgt verwendet werden können:

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

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

Das Verhalten von StringEscapeUtils.escapeXml () wurde von Commons Lang 2.5 auf 3.0 geändert. Unicode-Zeichen größer als 0x7f werden jetzt nicht mehr ausgeblendet.

Dies ist eine gute Sache. Die alte Methode bestand darin, Entitäten zu entkommen, die einfach in ein utf8-Dokument eingefügt werden konnten.

Die neuen Escaper in Google Guava 11.0 scheinen ebenfalls vielversprechend: http://code.google.com/p/guava-libraries/issues/detail?id=799

Jasper Krijgsman
quelle
1
Hier ist Guavas XML-Escaper: code.google.com/p/guava-libraries/source/browse/guava/src/com/… . Im Allgemeinen habe ich festgestellt, dass Guava besser aufgebaut ist als Apache Commons.
Jhclark
6

Für diejenigen, die nach der am schnellsten zu schreibenden Lösung suchen: Verwenden Sie Methoden von apache commons-lang :

Denken Sie daran, die Abhängigkeit einzuschließen:

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

Hinweis: Bei Ihrer Frage geht es um Escape und nicht um Codierung . Beim Escaping wird <usw. verwendet, damit der Parser zwischen "Dies ist ein XML-Befehl" und "Dies ist Text" unterscheiden kann. Die Codierung wird im XML-Header angegeben (UTF-8, ISO-8859-1 usw.).

Verwenden Sie zunächst, wie alle anderen sagten, eine XML-Bibliothek. XML sieht einfach aus, aber das Codieren + Escape-Material ist dunkles Voodoo (was Sie bemerken werden, sobald Sie auf Umlaute und japanische und andere seltsame Dinge wie " Ziffern voller Breite " stoßen (& # FF11; ist 1)). XML lesbar zu halten, ist eine Aufgabe von Sisyphus.

Ich schlage vor, niemals zu versuchen, klug in Bezug auf Textcodierung und Escape in XML zu sein. Aber lass dich nicht davon abhalten, es zu versuchen. Denken Sie daran, wann es Sie beißt (und es wird).

Wenn Sie jedoch nur UTF-8 verwenden, können Sie diese Strategie in Betracht ziehen, um die Lesbarkeit zu verbessern:

  • Wenn der Text '<', '>' oder '&' enthält, wickeln Sie ihn ein <![CDATA[ ... ]]>
  • Wenn der Text diese drei Zeichen nicht enthält, verzerren Sie ihn nicht.

Ich verwende dies in einem SQL-Editor und es ermöglicht den Entwicklern, SQL aus einem SQL-Tool eines Drittanbieters auszuschneiden und in das XML einzufügen, ohne sich Gedanken über das Entkommen machen zu müssen. Dies funktioniert, weil die SQL in unserem Fall keine Umlaute enthalten kann, also bin ich sicher.

Aaron Digulla
quelle
5

Obwohl ich Jon Skeet im Prinzip zustimme, habe ich manchmal nicht die Möglichkeit, eine externe XML-Bibliothek zu verwenden. Und ich finde es merkwürdig, dass die beiden Funktionen zum Escape / Unscape eines einfachen Werts (Attribut oder Tag, nicht vollständiges Dokument) in den in Java enthaltenen Standard-XML-Bibliotheken nicht verfügbar sind.

Als Ergebnis und basierend auf den verschiedenen Antworten, die ich hier und anderswo gesehen habe, ist hier die Lösung, die ich letztendlich erstellt habe (nichts hat als einfaches Kopieren / Einfügen funktioniert):

  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_LOW =  "" + ((char)0x20); //space
  private static String UNICODE_HIGH = "" + ((char)0x7f);

  //should only use 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 {
            stringBuilder.append("&#" + ((int)character.charAt(0)) + ";");
            modified = true;
          }
        }
      }
      if (modified) {
        result = stringBuilder.toString();
      }
    }

    return result;
  }

Das Obige berücksichtigt verschiedene Dinge:

  1. vermeidet die Verwendung von char-basierter Logik, bis dies unbedingt erforderlich ist - verbessert die Unicode-Kompatibilität
  2. Versuche, so effizient wie möglich zu sein, da die Wahrscheinlichkeit die zweite "Wenn" -Bedingung ist, ist wahrscheinlich der am häufigsten verwendete Weg
  3. ist eine reine Funktion; dh ist threadsicher
  4. Optimiert gut mit dem Garbage Collector, indem der Inhalt des StringBuilder nur zurückgegeben wird, wenn sich tatsächlich etwas geändert hat. Andernfalls wird der ursprüngliche String zurückgegeben

Irgendwann werde ich die Inversion dieser Funktion in Uncapsed () schreiben. Ich habe heute einfach keine Zeit dafür. Wenn ich das tue, werde ich diese Antwort mit dem Code aktualisieren. :) :)

chaotisches Gleichgewicht
quelle
Sieht für mich ziemlich gut aus. Ich möchte meinem Projekt kein weiteres Glas für nur eine Methode hinzufügen. Wenn Sie bitte die Erlaubnis erteilen, darf ich Ihren Code kopieren und in meinen einfügen?
RuntimeException
1
@ SatishMotwani Natürlich können Sie den obigen Code nehmen und damit machen, wie Sie möchten. Nach meinem Verständnis wird davon ausgegangen, dass jeder auf StackOverflow veröffentlichte Code urheberrechtsfrei ist (wird nicht als Gesamtwerk behandelt). Auf der anderen Seite wäre es für jemanden außerordentlich schwierig, irgendeine Art von Urheberrechtsanspruch geltend zu machen und ein Ergebnis für sich selbst zu erwarten.
chaotic3quilibrium
1
Danke fürs Erlauben :-) Ich werde es benutzen.
RuntimeException
Sie haben vergessen, mit NUL-Zeichen umzugehen. Und vielleicht auch andere Dinge.
David Balažic
3

Um XML-Zeichen zu entkommen, verwenden Sie am einfachsten das Apache Commons Lang-Projekt, JAR, das heruntergeladen werden kann von: http://commons.apache.org/lang/

Die Klasse lautet wie folgt: org.apache.commons.lang3.StringEscapeUtils;

Es hat eine Methode namens "EscapeXml", die einen entsprechend maskierten String zurückgibt.

Greg Burdett
quelle
Update: EscapeXml ist jetzt veraltet - benutze EscapeXml10. Ref commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/…
Daniel
3

Wenn Sie nach einer Bibliothek suchen, um die Arbeit zu erledigen, versuchen Sie:

  1. Guava 26.0 hier dokumentiert

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

    Hinweis: Es gibt auch eine xmlAttributeEscaper()

  2. Apache Commons Text 1.4 hier dokumentiert

    StringEscapeUtils.escapeXml11(text)

    Hinweis: Es gibt auch eine escapeXml10()Methode

jschnasse
quelle
1

Hier ist eine einfache Lösung, die sich auch hervorragend zum Codieren von Zeichen mit Akzent eignet!

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);

Ausgänge

Hi L&#226;rry &#38; M&#244;e!
Mike
quelle
Sollte nicht die "31" in der ersten Zeile des "wenn" "32" sein; dh weniger als das Leerzeichen? Und wenn "31" bleiben muss, sollte es dann nicht korrigiert werden, um "if (c <= 31 || ..." (zusätzliches Gleichheitszeichen nach dem
Kleiner
1

Einfach ersetzen

 & with &amp;

Und für andere Charaktere:

> with &gt;
< with &lt;
\" with &quot;
' with &apos;
Raman Rayat
quelle
0

Verwenden Sie JAXP und vergessen Sie die Textverarbeitung, die automatisch für Sie erledigt wird.

Fernando Miguélez
quelle
Ihr Link ist auf Spanisch, was für die meisten von uns nicht so hilfreich ist. Besser ist dieser .
Vivit
0

Versuchen Sie, das XML mit dem Apache XML-Serializer zu codieren

//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
quelle
0

Folgendes habe ich gefunden, nachdem ich überall nach einer Lösung gesucht habe:

Holen Sie sich die Jsoup-Bibliothek:

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

Dann:

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()

Hoffe das hilft jemandem

Wizston
quelle