জাভা বাদে এই প্রশ্নের সাথে খুব মিল ।
জাভাতে এক্সএমএল আউটপুটটির জন্য এনকোডিং স্ট্রিংয়ের প্রস্তাবিত উপায় কী। স্ট্রিংগুলিতে "&", "<" ইত্যাদির মতো অক্ষর থাকতে পারে etc.
জাভা বাদে এই প্রশ্নের সাথে খুব মিল ।
জাভাতে এক্সএমএল আউটপুটটির জন্য এনকোডিং স্ট্রিংয়ের প্রস্তাবিত উপায় কী। স্ট্রিংগুলিতে "&", "<" ইত্যাদির মতো অক্ষর থাকতে পারে etc.
উত্তর:
খুব সহজ: একটি এক্সএমএল লাইব্রেরি ব্যবহার করুন। এক্সএমএল অনুমানের বিটগুলির বিস্তারিত জ্ঞানের প্রয়োজনের পরিবর্তে এটি ঠিক ঠিক হবে।
অন্যরা যেমন উল্লেখ করেছেন, এক্সএমএল লাইব্রেরি ব্যবহার করা সহজতম উপায়। আপনি যদি নিজেকে পালাতে চান তবে আপনি অ্যাপাচি কমন্স ল্যাংগ্রন্থাগার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
।
এই প্রশ্নটি আট বছরের পুরানো এবং এখনও পুরোপুরি সঠিক উত্তর নয়! না, এই সাধারণ কাজটি করার জন্য আপনাকে একটি সম্পূর্ণ তৃতীয় পক্ষের API এম্পোর্ট করতে হবে না। খারাপ পরামর্শ।
নিম্নলিখিত পদ্ধতিটি করবে:
আমি সর্বাধিক সাধারণ ক্ষেত্রে অপ্টিমাইজ করার চেষ্টা করেছি, এখনও নিশ্চিত হয়েছি যে আপনি এর মাধ্যমে পাইপ / ডেভ / এলোমেলো করে এক্সএমএলে একটি বৈধ স্ট্রিং পেতে পারেন।
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();
}
সম্পাদনা করুন: এক্সএমএল মোকাবেলা করার জন্য পুরোপুরি ভাল জাভা এপিআই রয়েছে এমন লোকেরা এটির জন্য নিজের কোডটি লিখতে বোকামি করার জন্য জোর দিয়েছিলেন, আপনি জানতে চাইতে পারেন যে স্ট্যাকস এপিআই ওরেল জাভা 8 এর সাথে অন্তর্ভুক্ত রয়েছে (আমি অন্যদের পরীক্ষা করিনি) ) সিডিএটিএ কনটেন্টটি সঠিকভাবে এনকোড করতে ব্যর্থ হয়েছে: এটি এড়ায় না]]> সামগ্রীতে ক্রম। একটি তৃতীয় পক্ষের লাইব্রেরি, এমনকি একটি জাভা কোরের অংশ এটি সর্বদা সেরা বিকল্প নয়।
StringEscapeUtils.escapeXml()
নিয়ন্ত্রণের অক্ষরগুলি (<0x20) এড়ানো যায় না। এক্সএমএল 1.1 নিয়ন্ত্রণ অক্ষরের অনুমতি দেয়; এক্সএমএল 1.0 না। উদাহরণস্বরূপ, XStream.toXML()
জাভা অবজেক্টের নিয়ন্ত্রণ অক্ষরগুলি এক্সএমএলে আনন্দের সাথে সিরিয়ালাইজ করবে, যা একটি এক্সএমএল ০.০ পার্সার প্রত্যাখ্যান করবে।
অ্যাপাচি কমন্স-ল্যাং সহ নিয়ন্ত্রণের অক্ষরগুলি থেকে বাঁচতে ব্যবহার করুন
NumericEntityEscaper.below(0x20).translate(StringEscapeUtils.escapeXml(str))
public String escapeXml(String s) {
return s.replaceAll("&", "&").replaceAll(">", ">").replaceAll("<", "<").replaceAll("\"", """).replaceAll("'", "'");
}
replaceAll
কলগুলি খুব অদক্ষ, বিশেষত বড় স্ট্রিংগুলির জন্য। প্রতিটি কল ফলাফল তৈরি করে একটি নতুন স্ট্রিং অবজেক্ট তৈরি হয় যা আবর্জনা সংগ্রহ না করা অবধি ঘুরে বেড়াবে। এছাড়াও, প্রতিটি কলকে আবার স্ট্রিংয়ের মধ্য দিয়ে লুপিংয়ের প্রয়োজন হয়। এটি প্রতিটি পুনরাবৃত্তিতে প্রতিটি লক্ষ্য চরের বিপরীতে তুলনা সহ একটি একক ম্যানুয়াল লুপে একীকরণ করা যেতে পারে।
যদিও আদর্শবাদ বলছে একটি এক্সএমএল লাইব্রেরি ব্যবহার করুন, আইএমএইচও যদি আপনার এক্সএমএল সম্পর্কে প্রাথমিক ধারণা থাকে তবে সাধারণ জ্ঞান এবং অভিনয় এটি সমস্ত উপায়ে টেম্পলেট বলে। এটি তর্কসাপেক্ষে আরও পাঠযোগ্য। যদিও একটি লাইব্রেরির পালানোর রুটিনগুলি ব্যবহার করা সম্ভবত একটি ভাল ধারণা।
এটি বিবেচনা করুন: এক্সএমএল মানুষের দ্বারা রচিত হওয়া বোঝানো হয়েছিল ।
আপনার এক্সএমএলকে একটি "অবজেক্ট" আরও ভাল মডেল হিসাবে আপনার সমস্যা হিসাবে রাখার সময় এক্সএমএল তৈরি করার জন্য গ্রন্থাগারগুলি ব্যবহার করুন। উদাহরণস্বরূপ, যদি প্লাগেবল মডিউলগুলি এই এক্সএমএল তৈরির প্রক্রিয়াতে অংশ নেয়।
সম্পাদনা করুন: টেমপ্লেটগুলিতে কীভাবে এক্সএমএল escapeXml(string)
থেকে পালানো যায়, সিডিএটিএ বা জেএসটিএল থেকে দুটি ভাল সমাধান, escapeXml(string)
কীভাবে এটি ব্যবহার করা যেতে পারে:
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<item>${fn:escapeXml(value)}</item>
স্ট্রিংএস্কেপ ইউটিলস.সেসকেপ এক্সএমএল () এর আচরণ কমন্স ল্যাং 2.5 থেকে 3.0 এ পরিবর্তিত হয়েছে। এটি এখন 0x7f এর চেয়ে বড় ইউনিকোড অক্ষরগুলি থেকে বেরিয়ে যায়।
এটি একটি ভাল জিনিস, পুরানো পদ্ধতিটি সত্ত্বেও একটি utf8 নথিতে সন্নিবেশ করা যেতে পারে এমন সত্তাগুলি থেকে বাঁচতে আগ্রহী হওয়ার জন্য কিছুটা আগ্রহী ছিল।
গুগল পেয়ারা ১১.০-এ অন্তর্ভুক্ত করা নতুন এসকেপার্সগুলিও প্রতিশ্রুতিবদ্ধ বলে মনে হচ্ছে: http://code.google.com/p/guava-libraries/issues/detail?id=799
দ্রুত লেখার দ্রুত সমাধানের জন্য যারা খুঁজছেন তাদের জন্য: অ্যাপাচি কমন্স-ল্যাং থেকে পদ্ধতিগুলি ব্যবহার করুন :
StringEscapeUtils.escapeXml10()
এক্সএমএল 1.0 এর জন্যStringEscapeUtils.escapeXml11()
এক্সএমএল 1.1 এর জন্যStringEscapeUtils.escapeXml()
এখন অবহেলিত, তবে আগে সাধারণত ব্যবহৃত হতনির্ভরতা অন্তর্ভুক্ত মনে রাখবেন:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version> <!--check current version! -->
</dependency>
দ্রষ্টব্য: আপনার প্রশ্নটি এনকোডিং নয়, পালানোর বিষয়ে । "এটি একটি এক্সএমএল কমান্ড" এবং "এটি কিছু পাঠ্য" এর মধ্যে পার্সারকে পার্থক্য করার জন্য এস্কেপিং <, ইত্যাদি ব্যবহার করছে। এক্সএমএলিং হ'ল এক্সএমএল শিরোনাম (ইউটিএফ -8, আইএসও -8859-1, ইত্যাদি) এ আপনি নির্দিষ্ট করা জিনিস।
সবার আগে সবার মতোই, একটি এক্সএমএল লাইব্রেরি ব্যবহার করুন। এক্সএমএল দেখতে সহজ দেখায় তবে এনকোডিং + এস্কেপিং স্টাফ অন্ধকার ভোডু (যা আপনার মুখোমুখি হওয়ার সাথে সাথেই আপনি খেয়াল করতে পারবেন জাপানিজ এবং " সম্পূর্ণ প্রস্থের অঙ্কগুলি " এর মতো অন্যান্য অদ্ভুত স্টাফ (& # এফএফ 11; এটি 1%))। এক্সএমএল মানবকে পঠনযোগ্য রাখা সিসিফাসের কাজ।
আমি এক্সএমএলে পাঠ্য এনকোডিং এবং পালানোর বিষয়ে চালাক হওয়ার চেষ্টা করার পরামর্শ দিই না। তবে এটি আপনাকে চেষ্টা থেকে বিরত রাখবেন না; যখন মনে রাখবেন এটি কখন আপনাকে কামড়ায় (এবং এটি করবে)।
এটি বলেছে, আপনি যদি আরও UTF-8 ব্যবহার করেন তবে জিনিসগুলিকে আরও পাঠযোগ্য করে তোলার জন্য আপনি এই কৌশলটি বিবেচনা করতে পারেন:
<![CDATA[ ... ]]>
আমি এটি একটি এসকিউএল সম্পাদকটিতে ব্যবহার করছি এবং এটি বিকাশকারীদের উদ্বিগ্ন না করে কোনও তৃতীয় পক্ষের এসকিউএল সরঞ্জাম থেকে এসকিউএল কে এসএমএল কেটে পেস্ট করতে সহায়তা করে। এটি কাজ করে কারণ এসকিউএলটিতে আমাদের ক্ষেত্রে আমলাত থাকতে পারে না, তাই আমি নিরাপদ।
যদিও আমি জোন স্কিটির সাথে নীতিগতভাবে একমত, কখনও কখনও আমার কাছে বাহ্যিক এক্সএমএল লাইব্রেরি ব্যবহার করার বিকল্প নেই। এবং আমি এটিকে জাভির সাথে অন্তর্ভুক্ত স্ট্যান্ডার্ড এক্সএমএল লাইব্রেরিতে সহজ মান (অ্যাট্রিবিউট বা ট্যাগ নয়, সম্পূর্ণ ডকুমেন্ট নয়) থেকে অব্যাহতি / আনস্কেপ করতে দুটি ফাংশনটি অদ্ভুত বলে মনে করি।
ফলস্বরূপ এবং আমি এখানে এবং অন্য কোথাও পোস্ট করা বিভিন্ন উত্তরগুলির উপর ভিত্তি করে, সমাধানটি তৈরি করে শেষ করেছি (সাধারণ অনুলিপি / পেস্ট হিসাবে কিছুই কাজ করেনি):
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;
}
উপরোক্ত কয়েকটি বিভিন্ন জিনিস সমন্বয় করে:
এক পর্যায়ে, আমি এই ফাংশনটির বিপরীতটি লিখব, টু ইউনেস্কেপড ()। আমার আজকের সময়টি করার মতো সময় নেই। আমি যখন করব, কোড সহ এই উত্তরটি আপডেট করব update :)
null
। আপনি দুটি মানের সংজ্ঞা ব্যাখ্যা করতে পারেন, UNICODE_LOW
এবং UNICODE_HIGH
? if
এই দুটি মান ব্যবহার করে দয়া করে এটি পুনরায় পড়ুন । লক্ষ্য করুন null
( \u0000
যা হয় (int)0
) এই দুটি মানের মধ্যে পড়ে না। কৌশলটি ব্যবহার করে কীভাবে এটি সঠিকভাবে "পালিয়ে যায়" ঠিক তেমনভাবে সমস্ত প্যানেল UNICODE_LOW
এবং UNICODE_HIGH
রেঞ্জের বাইরে বিদ্যমান ইউনিকোড অক্ষরগুলির মতো হয় escaped &#
এক্সএমএল অক্ষরগুলি থেকে বাঁচতে, সবচেয়ে সহজ উপায় হ'ল অ্যাপাচি কমন্স ল্যাং প্রকল্পটি, জেআর থেকে ডাউনলোডযোগ্য: http://commons.apache.org/lang/
শ্রেণিটি হ'ল: org.apache.commons.lang3.StringEcreenUtils;
এটির "এসএক্সএক্সএমএল" নামক একটি পদ্ধতি রয়েছে যা যথাযথভাবে পালানো স্ট্রিংকে ফিরিয়ে দেবে।
আপনি যদি কাজটি পেতে কোনও গ্রন্থাগার সন্ধান করছেন তবে চেষ্টা করুন:
পেয়ারা 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!
আপনি ব্যবহার করতে পারে এন্টারপ্রাইজ সিকিউরিটি এপিআই (ESAPI) গ্রন্থাগারের , যা মত পদ্ধতি প্রদান করে encodeForXML
এবং encodeForXMLAttribute
। এনকোডার ইন্টারফেসের ডকুমেন্টেশন একবার দেখুন ; এটিতে ডিফল্ট এনকোডারটির উদাহরণ কীভাবে তৈরি করা যায় তার উদাহরণ রয়েছে ।
জ্যাকএক্সপি ব্যবহার করুন এবং পাঠ্য হ্যান্ডলিংয়ের কথা ভুলে যান এটি আপনার জন্য স্বয়ংক্রিয়ভাবে হয়ে যাবে।
অ্যাপাচি এক্সএমএল সিরিয়ালাইজার ব্যবহার করে এক্সএমএলকে এনকোড করার চেষ্টা করুন
//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());
সমাধান অনুসন্ধানের জন্য সর্বত্র অনুসন্ধান করার পরে আমি যা পেয়েছি তা এখানে:
জসপ লাইব্রেরি পান:
<!-- 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()
আশা করি এটি কাউকে সাহায্য করবে
আমি এখানে আমার মোড়ক তৈরি করেছি, আশা করি এটি অনেক উপকারে আসবে, এখানে ক্লিক করুন আপনি আপনার প্রয়োজনীয়তার উপর নির্ভর করে পরিবর্তন করতে পারেন