जावा को छोड़कर, इस प्रश्न के समान ही ।
जावा में XML आउटपुट के लिए एन्कोडिंग स्ट्रिंग्स का अनुशंसित तरीका क्या है। तार में "और", "<", आदि जैसे अक्षर हो सकते हैं।
जावा को छोड़कर, इस प्रश्न के समान ही ।
जावा में XML आउटपुट के लिए एन्कोडिंग स्ट्रिंग्स का अनुशंसित तरीका क्या है। तार में "और", "<", आदि जैसे अक्षर हो सकते हैं।
जवाबों:
बहुत सरलता से: एक XML पुस्तकालय का उपयोग करें। इस तरह यह एक्सएमएल कल्पना के बिट्स के विस्तृत ज्ञान की आवश्यकता के बजाय वास्तव में सही होगा ।
जैसा कि दूसरों ने उल्लेख किया है, XML लाइब्रेरी का उपयोग करना सबसे आसान तरीका है। यदि आप खुद को बचाना चाहते हैं, तो आप अपाचे कॉमन्स लैंग लाइब्रेरी StringEscapeUtils
से देख सकते हैं ।
StringEscapeUtils.escapeXml(str)
से commons-lang
। मैं इसे ऐप इंजन एप्लिकेशन में उपयोग करता हूं - एक आकर्षण की तरह काम करता हूं। इस कार्य के लिए जावा डॉक यहां दिया गया है :
\t
, \n
और \r
।
\t
, \n
या \r
भागने की जरूरत है?
महज प्रयोग करें।
<![CDATA[ your text here ]]>
यह अंत को छोड़कर किसी भी वर्ण को अनुमति देगा
]]>
तो आप ऐसे वर्णों को शामिल कर सकते हैं जो अवैध होंगे जैसे &>। उदाहरण के लिए।
<element><![CDATA[ characters such as & and > are allowed ]]></element>
हालांकि, विशेषताओं को बचाना होगा क्योंकि सीडीएटीए ब्लॉक का उपयोग उनके लिए नहीं किया जा सकता है।
यह मेरे लिए एक पाठ स्ट्रिंग के बच गए संस्करण प्रदान करने के लिए अच्छी तरह से काम किया है:
public class XMLHelper {
/**
* Returns the string where all non-ascii and <, &, > are encoded as numeric entities. I.e. "<A & B >"
* .... (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();
}
}
इसे इस्तेमाल करे:
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("<"); break;
case '>': sb.append(">"); break;
case '\"': sb.append("""); break;
case '&': sb.append("&"); break;
case '\'': sb.append("'"); break;
default:
if(c>0x7e) {
sb.append("&#"+((int)c)+";");
}else
sb.append(c);
}
}
return sb.toString();
}
t==null
।
यह सवाल आठ साल पुराना है और अभी भी पूरी तरह से सही जवाब नहीं है! नहीं, आपको इस सरल कार्य को करने के लिए पूरे तृतीय पक्ष एपीआई का आयात नहीं करना चाहिए। बुरी सलाह।
निम्नलिखित विधि होगी:
मैंने सबसे आम मामले के लिए अनुकूलन करने की कोशिश की है, जबकि अभी भी यह सुनिश्चित करता है कि आप इसके माध्यम से पाइप / देव / यादृच्छिक कर सकते हैं और 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("�"); // Unicode replacement character
} else {
switch(c) {
case '&': sb.append("&"); break;
case '>': sb.append(">"); break;
case '<': sb.append("<"); break;
// Uncomment next two if encoding for an XML attribute
// case '\'' sb.append("'"); break;
// case '\"' sb.append("""); break;
// Uncomment next three if you prefer, but not required
// case '\n' sb.append(" "); break;
// case '\r' sb.append(" "); break;
// case '\t' sb.append("	"); 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("�"); // Unicode replacement character
} else {
sb.append("&#x");
sb.append(Integer.toHexString(c));
sb.append(';');
}
}
return sb.toString();
}
संपादित करें: जो लोग इसे जारी रखना चाहते हैं, वे इसके लिए अपना कोड लिखने की मूर्खता करते हैं जब XML से निपटने के लिए पूरी तरह से अच्छे जावा एपीआई हैं, तो आप यह जानना चाह सकते हैं कि ओरेकल जावा 8 के साथ शामिल StAX API (मैंने दूसरों का परीक्षण नहीं किया है ) CDATA सामग्री को सही तरीके से एनकोड करने में विफल रहता है: यह बच नहीं पाता]]> सामग्री में अनुक्रम। एक तृतीय पक्ष पुस्तकालय, यहां तक कि जावा कोर का एक हिस्सा, हमेशा सबसे अच्छा विकल्प नहीं होता है।
StringEscapeUtils.escapeXml()
नियंत्रण पात्रों से बच नहीं है (<0x20)। एक्सएमएल 1.1 नियंत्रण पात्रों की अनुमति देता है; एक्सएमएल 1.0 नहीं है। उदाहरण के लिए,XStream.toXML()
एक्सएमएल में जावा ऑब्जेक्ट के नियंत्रण वर्णों को खुशी से क्रमबद्ध करेगा, जिसे एक्सएमएल 1.0 पार्सर अस्वीकार कर देगा।
अपाचे कॉमन्स-लैंग के साथ नियंत्रण पात्रों से बचने के लिए, का उपयोग करें
NumericEntityEscaper.below(0x20).translate(StringEscapeUtils.escapeXml(str))
public String escapeXml(String s) {
return s.replaceAll("&", "&").replaceAll(">", ">").replaceAll("<", "<").replaceAll("\"", """).replaceAll("'", "'");
}
replaceAll
कॉल विशेष रूप से बड़ी स्ट्रिंग्स के लिए, बहुत अक्षम है। हर कॉल के परिणामस्वरूप एक नई स्ट्रिंग ऑब्जेक्ट बनाई जा रही है, जो कचरा एकत्र होने तक घूमती रहेगी। इसके अलावा, प्रत्येक कॉल को फिर से स्ट्रिंग के माध्यम से लूपिंग की आवश्यकता होती है। यह एक एकल मैनुअल लूप में समेकित किया जा सकता है, जिसमें प्रत्येक पुनरावृत्ति में प्रत्येक लक्ष्य चार के खिलाफ तुलना होती है।
जबकि आदर्शवाद कहता है कि एक XML पुस्तकालय, IMHO का उपयोग करें यदि आपके पास XML का एक मूल विचार है तो सामान्य ज्ञान और प्रदर्शन का कहना है कि यह सभी तरह से टेम्पलेट है। यकीनन यह अधिक पठनीय है। हालांकि एक पुस्तकालय के भागने की दिनचर्या का उपयोग करना शायद एक अच्छा विचार है।
इस पर विचार करें: XML था मतलब मनुष्यों द्वारा लिखा जाना ।
XML को "ऑब्जेक्ट" के रूप में आपके समस्या के बेहतर मॉडल होने पर XML उत्पन्न करने के लिए पुस्तकालयों का उपयोग करें। उदाहरण के लिए, अगर प्लग करने योग्य मॉड्यूल इस XML के निर्माण की प्रक्रिया में भाग लेते हैं।
संपादित करें: वास्तव में XML को टेम्प्लेट escapeXml(string)
से कैसे बचाना है, सीडीएटीए का उपयोग या जेएसटीएल से दो अच्छे समाधान हैं, escapeXml(string)
इसका उपयोग इस तरह किया जा सकता है:
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<item>${fn:escapeXml(value)}</item>
StringEscapeUtils.escapeXml () का व्यवहार कॉमन्स लैंग 2.5 से 3.0 में बदल गया है। यह अब 0x7f से अधिक यूनिकोड वर्णों से नहीं बचता है।
यह एक अच्छी बात है, पुरानी पद्धति को उन संस्थाओं से बचने के लिए थोड़ा उत्सुक होना था जिन्हें केवल utf8 दस्तावेज़ में डाला जा सकता था।
Google Guava 11.0 में शामिल किए जाने वाले नए एस्कैपर्स भी आशाजनक प्रतीत होते हैं: http://code.google.com/p/guava-lbooks/issues/detail?id=799
शीघ्र समाधान की तलाश करने वालों के लिए: अपाचे कॉमन्स-लैंग से विधियों का उपयोग करें :
StringEscapeUtils.escapeXml10()
xml 1.0 के लिएStringEscapeUtils.escapeXml11()
xml 1.1 के लिएStringEscapeUtils.escapeXml()
अब पदावनत कर दिया गया है, लेकिन अतीत में आमतौर पर इसका इस्तेमाल किया जाता थानिर्भरता को शामिल करना याद रखें:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version> <!--check current version! -->
</dependency>
नोट: आपका प्रश्न बचने के बारे में है , एन्कोडिंग के बारे में नहीं । बचने के लिए <, आदि का उपयोग कर रहा है ताकि पार्सर को "यह एक XML कमांड है" और "यह कुछ पाठ है" के बीच अंतर करने की अनुमति मिल सके। एनकोडिंग XML हेडर (UTF-8, ISO-8859-1, आदि) में आपके द्वारा निर्दिष्ट सामान है।
सबसे पहले, जैसा कि सभी ने कहा, XML लाइब्रेरी का उपयोग करें। XML सरल दिखता है, लेकिन एन्कोडिंग + बचकर निकलने वाला सामान डार्क वूडू है (जिसे आप umlauts और जापानी और अन्य अजीब सामान जैसे " पूर्ण चौड़ाई अंक " (& # FF11; 1 है;) से मिलते ही नोटिस करेंगे । XML मानव को पठनीय रखना एक Sisyphus का कार्य है।
मेरा सुझाव है कि XML में पाठ एन्कोडिंग और भागने के बारे में चतुर होने की कोशिश न करें। लेकिन ऐसा मत करो कि तुम कोशिश करना बंद करो; बस याद रखें जब यह आपको काटता है (और यह होगा)।
कहा कि, यदि आप केवल UTF-8 का उपयोग करते हैं, तो चीजों को अधिक पठनीय बनाने के लिए आप इस रणनीति पर विचार कर सकते हैं:
<![CDATA[ ... ]]>
मैं SQL संपादक में इसका उपयोग कर रहा हूं और यह डेवलपर्स को बचने के बारे में चिंता किए बिना XML में एक तीसरे पक्ष के SQL उपकरण से SQL को काटने और पेस्ट करने की अनुमति देता है। यह काम करता है क्योंकि SQL में हमारे मामले में umlauts नहीं हो सकते हैं, इसलिए मैं सुरक्षित हूं।
जबकि मैं सिद्धांत रूप में जॉन स्कीट से सहमत हूं, कभी-कभी मेरे पास बाहरी XML लाइब्रेरी का उपयोग करने का विकल्प नहीं होता है। और मुझे लगता है कि यह एक साधारण मूल्य (विशेषता या टैग, पूर्ण दस्तावेज़ नहीं) को हटाने के लिए दो कार्यों को अजीब बनाता है, जावा के साथ शामिल मानक XML पुस्तकालयों में उपलब्ध नहीं हैं।
परिणामस्वरूप और विभिन्न उत्तरों के आधार पर जो मैंने यहां और अन्य जगहों पर पोस्ट किए हैं, यहां समाधान है जो मैंने तैयार किया है (कुछ भी सरल कॉपी / पेस्ट के रूप में काम नहीं किया गया है):
public final static String ESCAPE_CHARS = "<>&\"\'";
public final static List<String> ESCAPE_STRINGS = Collections.unmodifiableList(Arrays.asList(new String[] {
"<"
, ">"
, "&"
, """
, "'"
}));
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;
}
उपरोक्त कई अलग-अलग चीजों को समायोजित करता है:
कुछ बिंदु पर, मैं इस समारोह के उलटा लिखूंगा, toUnescaped ()। मेरे पास आज ऐसा करने का समय नहीं है। जब मैं करता हूं, तो मैं इस उत्तर को कोड के साथ अपडेट करूंगा। :)
null
। क्या आप दो मूल्यों की परिभाषा समझा सकते हैं, UNICODE_LOW
और UNICODE_HIGH
? कृपया if
उन दो मूल्यों का उपयोग करने वाले को फिर से विभाजित करें । सूचना null
( \u0000
जो है (int)0
) इन दो मूल्यों के बीच नहीं आती है। तकनीक का उपयोग करके यह पढ़ें कि यह कैसे ठीक से "एस्केप" हो गया, जैसे कि सभी यूनिकोड वर्ण बाहर UNICODE_LOW
और UNICODE_HIGH
सीमा के बाहर मौजूद हैं &#
।
XML वर्णों से बचने के लिए, सबसे आसान तरीका अपाचे कॉमन्स लैंग परियोजना, जार डाउनलोड से उपयोग करना है: http://commons.apache.org/lang/
वर्ग यह है: org.apache.commons.lang3.StringEscapeUtils;
इसमें "एस्केपएक्सएमएल" नाम की एक विधि है, जो उचित रूप से बची हुई स्ट्रिंग को लौटा देगी।
यदि आप नौकरी पाने के लिए पुस्तकालय की तलाश कर रहे हैं, तो प्रयास करें:
यहां अमरूद 26.0 प्रलेखित है
return XmlEscapers.xmlContentEscaper().escape(text);
नोट: एक भी है
xmlAttributeEscaper()
अपाचे कॉमन्स टेक्स्ट 1.4 ने यहाँ दस्तावेज़ दिया है
StringEscapeUtils.escapeXml11(text)
नोट: एक
escapeXml10()
विधि भी है
यहाँ एक आसान समाधान है और यह उच्चारण पात्रों को एन्कोडिंग के लिए बहुत अच्छा है!
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);
आउटपुट
Hi Lârry & Môe!
आप एंटरप्राइज़ सिक्योरिटी एपीआई (ईएसएपीआई) लाइब्रेरी का उपयोग कर सकते हैं , जो इस तरह के तरीके encodeForXML
और प्रदान करता है encodeForXMLAttribute
। एनकोडर इंटरफेस के प्रलेखन पर एक नज़र डालें ; इसमें DefaultEncoder का उदाहरण कैसे बनाया जाए, इसके उदाहरण भी हैं ।
JAXP का उपयोग करें और पाठ हैंडलिंग के बारे में भूल जाएं यह आपके लिए स्वचालित रूप से किया जाएगा।
Apache XML सीरियलएज़र का उपयोग करके XML को एन्कोड करने का प्रयास करें
//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());
समाधान खोजने के लिए हर जगह खोज करने के बाद मैंने यहां क्या पाया:
Jsoup लाइब्रेरी प्राप्त करें:
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
</dependency>
फिर:
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()
आशा है कि यह किसी की मदद करता है