এক্সএমএল সিরিয়ালাইজেশনের জন্য স্ট্রিং রাইটার ব্যবহার করা


99

আমি বর্তমানে অবজেক্টগুলিকে সিরিয়ালাইজ করার একটি সহজ উপায় সন্ধান করছি (সি # 3 এ)।

আমি কয়েকটি উদাহরণ গুগল করেছিলাম এবং এরকম কিছু নিয়ে এসেছি:

MemoryStream memoryStream = new MemoryStream ( );
XmlSerializer xs = new XmlSerializer ( typeof ( MyObject) );
XmlTextWriter xmlTextWriter = new XmlTextWriter ( memoryStream, Encoding.UTF8 );
xs.Serialize ( xmlTextWriter, myObject);
string result = Encoding.UTF8.GetString(memoryStream .ToArray());

এই প্রশ্নটি পড়ার পরে আমি নিজেকে জিজ্ঞাসা করেছি, স্ট্রিং রাইটার ব্যবহার করছেন না কেন? এটা অনেক সহজ মনে হয়।

XmlSerializer ser = new XmlSerializer(typeof(MyObject));
StringWriter writer = new StringWriter();
ser.Serialize(writer, myObject);
serializedValue = writer.ToString();

আরেকটি সমস্যা হ'ল প্রথম উদাহরণটি XML উত্পন্ন হয়েছে আমি কেবল এসকিউএল সার্ভার 2005 ডিবি-এর একটি এক্সএমএল কলামে লিখতে পারি নি।

প্রথম প্রশ্নটি: আমার যখন স্ট্রিং রাইটারটি স্ট্রিংয়ের পরে যখন স্ট্রিংয়ের প্রয়োজন হয় তখন কোনও অবজেক্টের ক্রমিকায়িত করার জন্য আমার কেন ব্যবহার করা উচিত নয়? গুগল করার সময় আমি স্ট্রিং রাইটার ব্যবহার করে কোনও ফলাফল পাইনি।

দ্বিতীয়টি অবশ্যই: যদি আপনার স্ট্রিং রাইটার (যে কারণেই না হয়) দিয়ে এটি না করা হয়, তবে এটি একটি ভাল এবং সঠিক উপায় হতে পারে?


সংযোজন:

এটি ইতিমধ্যে উভয় উত্তর দ্বারা উল্লিখিত ছিল, আমি আরও XML থেকে ডিবি সমস্যার মধ্যে যাব।

ডাটাবেসে লেখার সময় আমি নিম্নলিখিত ব্যতিক্রম পেয়েছি:

System.Data.SqlClient.SqlException: XML পার্সিং: লাইন 1, অক্ষর 38, এনকোডিং পরিবর্তন করতে অক্ষম

স্ট্রিং জন্য

<?xml version="1.0" encoding="utf-8"?><test/>

আমি XMLTextWriter থেকে তৈরি স্ট্রিংটি নিয়েছি এবং কেবল সেখানে xML হিসাবে রেখেছি। এইটি কাজ করে নি (কোনও ডিবিতে ম্যানুয়াল সন্নিবেশ সহ)।

এরপরে আমি ম্যানুয়াল সন্নিবেশের চেষ্টা করেছি (কেবল লিখুন INSERT INTO ...) এনকোডিং সহ "" utf-16 "যা ব্যর্থ হয়েছিল। তখন এনকোডিং সরানো পুরোপুরি কাজ করে। ফলাফলের পরে আমি স্ট্রিং রাইটার কোড এবং ভয়েলাতে ফিরে এসেছি - এটি কাজ করে।

সমস্যা: কেন আসলে তা বুঝতে পারছি না।

ক্রিশ্চান হাইটারে: এই পরীক্ষাগুলির সাথে আমি নিশ্চিত নই যে ডিবিতে লেখার জন্য আমাকে utf-16 ব্যবহার করতে হবে। ইউটিএফ -16 এ (এনএমএল ট্যাগে) তখন এনকোডিংটি সেট করবেন না?


4
আমি ব্যক্তিগত অভিজ্ঞতা যাচ্ছি। এসকিউএল সার্ভার কেবলমাত্র ইউটিএফ -১ accep গ্রহণ করে এবং আপনি যদি এটিকে অন্য কোনও কিছু থেকে পাস করেন তবে আপনি এসকিউএল সার্ভার এক্সএমএল পার্সার এবং ডেটা রূপান্তর করার জন্য এর প্রয়াসে রয়েছেন। এটিকে বোকা বানানোর কোনও উপায় অনুসন্ধান করার চেষ্টা না করে, আমি কেবল এটি ইউটিএফ -16 সরাসরি সরাসরি পাস করি, যা সর্বদা কার্যকর হবে।
ক্রিশ্চান হাইটার

আপনি কীভাবে এটি ডাটাবেসে লিখছেন? আপনি কি এটি একটি স্ট্রিং, বা বাইটের একটি অ্যারে, বা একটি স্ট্রিমে লিখছেন? যদি এটি পরবর্তী দুটি রূপগুলির মধ্যে দুটি হয় তবে আপনাকে অবশ্যই নিশ্চিত করতে হবে যে আপনার ঘোষিত এনকোডিংটি আপনার বাইনারি ডেটার প্রকৃত এনকোডিংয়ের সাথে মেলে।
জন স্কিটি

ভাই এমএস এসকিউএল ম্যানেজমেন্ট স্টুডিওতে ক্যোয়ারী হিসাবে ম্যানুয়াল চেষ্টা করেছি। "কোডেড" চেষ্টাগুলি একটি স্ট্রিংয়ে লেখা হয়েছিল যা তারপরে একটি ও / আর ম্যাপারকে দেওয়া হয়েছিল যা একটি স্ট্রিং হিসাবে লেখায় (যতদূর আমি অনুসরণ করতে পারি)। আসলে আমি এটিকে স্ট্রিং দিয়ে যাচ্ছি যা আমার প্রশ্নের দেওয়া দুটি উদাহরণে তৈরি হয়েছিল।
স্ট্যাম্পেডএক্সভি

অবগতির জন্য পাঠকদের কাছে - কাছাকাছি অনুরূপ: stackoverflow.com/questions/384974/... এবং stackoverflow.com/questions/3760788/...
ziesemer

4
আমি আমার গৃহীত উত্তর পরিবর্তন করছি কারণ আমি বিশ্বাস করি এটি আসলে আমার প্রশ্নের উত্তর দেয়। যদিও অন্যান্য উত্তরগুলি আমাকে আমার কাজ চালিয়ে যেতে সহায়তা করছে, স্ট্যাকওভারফ্লোয়ের উদ্দেশ্যে আমি মনে করি সলোমনের উত্তর অন্যদের কী হয়েছে তা আরও ভালভাবে বুঝতে সহায়তা করবে। [অস্বীকৃতি]: উত্তরটি সত্যিই যাচাই করার জন্য আমি সময় পাইনি।
স্ট্যাম্পেডিএক্সভি

উত্তর:


1

<টিএল; ডিআর> সমস্যাটি বরং সাধারণ, আসলে: আপনি ইনপুট প্যারামিটারের ডেটাটাইপের সাথে ঘোষিত এনকোডিংটি (এক্সএমএল ঘোষণায়) মেলাচ্ছেন না। আপনি যদি ম্যানুয়ালি <?xml version="1.0" encoding="utf-8"?><test/>স্ট্রিংয়ে যুক্ত হন, তবে SqlParameterএটিকে টাইপযুক্ত হিসাবে ঘোষণা করে SqlDbType.Xmlবা SqlDbType.NVarCharআপনাকে "এনকোডিং স্যুইচ করতে অক্ষম" ত্রুটি দেয় give তারপরে, টি-এসকিউএল এর মাধ্যমে ম্যানুয়ালি সন্নিবেশ করার সময় utf-16, আপনি ঘোষিত এনকোডিংটি যেহেতু স্যুইচ করেছেন , আপনি স্পষ্টভাবে একটি VARCHARস্ট্রিং সন্নিবেশ করছিলেন (উচ্চ-কেস "এন" এর সাথে উপস্থাপিত হয়নি, সুতরাং একটি 8-বিট এনকোডিং যেমন ইউটিএফ -8) এবং একটি NVARCHARস্ট্রিং নয় (একটি উচ্চ-কেস "N" এর সাথে উপসর্গযুক্ত, সুতরাং 16 বিট ইউটিএফ -16 এলই এনকোডিং)।

ফিক্সটি এতটা সহজ হওয়া উচিত:

  1. প্রথম ক্ষেত্রে, ঘোষণাটি যুক্ত করার সময় উল্লেখ করুন encoding="utf-8": কেবল এক্সএমএল ঘোষণাটি যুক্ত করবেন না।
  2. দ্বিতীয় ক্ষেত্রে, ঘোষণাপত্রটি যুক্ত করার সময় উল্লেখ করুন encoding="utf-16": হয়
    1. কেবল এক্সএমএল ঘোষণাটি যুক্ত করবেন না, বা
    2. ইনপুট প্যারামিটার প্রকারে কেবল একটি "এন" যুক্ত করুন: :-) এর SqlDbType.NVarCharপরিবর্তে SqlDbType.VarChar(অথবা সম্ভবত ব্যবহারে স্যুইচ করুন SqlDbType.Xml)

(বিস্তারিত প্রতিক্রিয়া নীচে রয়েছে)


এখানে সমস্ত উত্তর অত্যধিক জটিল এবং অপ্রয়োজনীয় (যথাক্রমে খ্রিস্টান এবং জনের উত্তরের জন্য 121 এবং 184-এর আপ-ভোট নির্বিশেষে)। তারা হয়ত ওয়ার্কিং কোড সরবরাহ করতে পারে তবে তাদের কেউই আসলে প্রশ্নের উত্তর দেয় না। সমস্যাটি হ'ল এই প্রশ্নটি কেউ সত্যই বুঝতে পারে নি, যা শেষ পর্যন্ত এসকিউএল সার্ভারে এক্সএমএল ডেটাটাইপ কীভাবে কাজ করে তা সম্পর্কে। এই দু'টি স্পষ্ট বুদ্ধিমান ব্যক্তির বিরুদ্ধে কিছুই নয়, তবে এক্সএমএলকে সিরিয়ালায়িত করার সাথে এই প্রশ্নের কিছুটা করার নেই। এসকিউএল সার্ভারে এক্সএমএল ডেটা সংরক্ষণ করা এখানে যা বোঝানো হচ্ছে তার চেয়ে অনেক সহজ।

আপনি এসকিউএল সার্ভারে কীভাবে এক্সএমএল ডেটা তৈরি করবেন তার নিয়মগুলি মেনে চলেন যতক্ষণ না এক্সএমএল উত্পাদিত হয় তা বিবেচ্য নয়। এই প্রশ্নের উত্তরে আমার আরও বিশদ ব্যাখ্যা রয়েছে (নীচে বর্ণিত পয়েন্টগুলি বর্ণনা করার জন্য ওয়ার্কিং উদাহরণ কোড সহ) এসকিউএল সার্ভারে এক্সএমএল সন্নিবেশ করার সময় কীভাবে "এনকোডিং স্যুইচ করতে অক্ষম" ত্রুটিটি সমাধান করা যায় তবে মূল বিষয়গুলি হ'ল:

  1. এক্সএমএল ঘোষণাটি isচ্ছিক
  2. এক্সএমএল ডেটাটাইপ সর্বদা ইউসিএস -2 / ইউটিএফ -16 এলই হিসাবে স্ট্রিং সঞ্চয় করে
  3. যদি আপনার এক্সএমএলটি ইউসিএস -২ / ইউটিএফ -16 এলই হয়, তবে আপনি:
    1. ডেটাটি হয় NVARCHAR(MAX)বা XML/ SqlDbType.NVarChar(ম্যাক্সেসাইজ = -1) হিসাবে পাস করুন SqlDbType.Xml, বা যদি স্ট্রিং আক্ষরিক ব্যবহার করে থাকেন তবে অবশ্যই এটি একটি উচ্চ-কেস "এন" এর সাথে উপসর্গ করা উচিত।
    2. যদি এক্সএমএল ঘোষণাটি নির্দিষ্ট করে থাকে তবে এটি অবশ্যই "ইউসিএস -২" বা "ইউটিএফ -16" হতে হবে (এখানে কোনও আসল পার্থক্য নেই)
  4. যদি আপনার এক্সএমএল 8-বিট এনকোডড থাকে (উদাঃ "ইউটিএফ -8" / "আইসো -8859-1" / "উইন্ডোজ-1252") তবে আপনি:
    1. এক্সএমএল ঘোষণাটি নির্দিষ্ট করতে হবে যদি এনকোডিংটি ডাটাবেজের ডিফল্ট কোলেশন দ্বারা নির্দিষ্ট কোড পৃষ্ঠার চেয়ে আলাদা হয়
    2. আপনাকে অবশ্যই ডেটাতে VARCHAR(MAX)/ SqlDbType.VarChar(ম্যাক্সেসাইজ = -1) হিসাবে পাস করতে হবে , বা যদি স্ট্রিং আক্ষরিক ব্যবহার করে থাকে তবে অবশ্যই এটি একটি উচ্চ-কেস "এন" এর সাথে উপস্থাপিত হবে না
    3. 8-বিট এনকোডিং যাই ব্যবহার করা হোক না কেন, এক্সএমএল ঘোষণায় উল্লিখিত "এনকোডিং" অবশ্যই বাইটের প্রকৃত এনকোডিংয়ের সাথে মিলে যাবে।
    4. 8 বিট এনকোডিংটি এক্সএমএল ডেটাটাইপ দ্বারা UTF-16 এলিতে রূপান্তরিত হবে

উপরে উল্লিখিত পয়েন্টগুলি মাথায় রেখে এবং স্ট্রিংগুলি দেওয়া হয়েছে। নেট সর্বদা ইউটিএফ -16 এলই / ইউসিএস -2 এলই হয় (এনকোডিংয়ের ক্ষেত্রে এটির মধ্যে কোনও পার্থক্য নেই), আমরা আপনার প্রশ্নের উত্তর দিতে পারি:

আমার যখন স্ট্রিং রাইটারটি স্ট্রিংয়ের পরে যখন স্ট্রিংয়ের প্রয়োজন হয় তখন কোনও অবজেক্টের সিরিয়ালাইজ করার জন্য আমার ব্যবহার না করা কেন এমন কোনও কারণ আছে?

না, আপনার StringWriterকোডটি ঠিক আছে বলে মনে হচ্ছে (কমপক্ষে আমি প্রশ্ন থেকে ২ য় কোড ব্লক ব্যবহার করে আমার সীমাবদ্ধ পরীক্ষায় কোনও সমস্যা দেখছি না)।

ইউটিএফ -16 এ (এনএমএল ট্যাগে) তখন এনকোডিংটি সেট করবেন না?

এক্সএমএল ঘোষণা সরবরাহ করার প্রয়োজন নেই। এটি অনুপস্থিত থাকলে, এনকোডিংটি ইউটিএফ -১ LE লে হিসাবে ধরে নেওয়া হয় যদি আপনি এসকিউএল সার্ভারে NVARCHAR(যেমন SqlDbType.NVarChar) বা XML(ie SqlDbType.Xml) হিসাবে স্ট্রিংটি পাস করেন । VARCHAR(যেমন SqlDbType.VarChar) হিসাবে পাস করার সাথে সাথে এনকোডিংটি ডিফল্ট 8-বিট কোড পৃষ্ঠা হিসাবে ধরে নেওয়া হয় । আপনার যদি কোনও মানহীন-এএসসিআইআই অক্ষর থাকে (উদাহরণস্বরূপ 128 এবং এর চেয়ে বেশি মান) এবং এরূপ হিসাবে চলে যাচ্ছেনVARCHAR তবে আপনি সম্ভবত দেখতে পাবেন "?" বিএমপি অক্ষরের জন্য এবং "??" এসকিউএল সার্ভার হিসাবে পরিপূরক অক্ষরের জন্য ইউটিএফ -১ / / ইউসিএস -২ এ আবার রূপান্তর করার আগে ইউটিএফ -১ string স্ট্রিংটিকে বর্তমান নেটবেস-এর কোড পৃষ্ঠার .NET থেকে একটি 8-বিট স্ট্রিংয়ে রূপান্তর করবে। তবে আপনার কোনও ত্রুটি হওয়া উচিত নয়।

অন্যদিকে, আপনি যদি এক্সএমএল ঘোষণাটি নির্দিষ্ট করে থাকেন তবে অবশ্যই আপনাকে 8-বিট বা 16-বিট ডেটাটাইপটি ম্যাচিং করে এসকিউএল সার্ভারে প্রবেশ করতে হবে । সুতরাং যদি আপনার কাছে কোনও ঘোষণা রয়েছে যে এনকোডিংটি হয় ইউসিএস -২ বা ইউটিএফ -16, তবে আপনাকে অবশ্যই হিসাবে SqlDbType.NVarCharবা হিসাবে পাস করতে হবেSqlDbType.Xml । অথবা, যদি আপনার কাছে কোনও ঘোষণা থাকে যা উল্লেখ করে যে এনকোডিংটি 8-বিট বিকল্পগুলির মধ্যে একটি (যেমনUTF-8 , Windows-1252, iso-8859-1, ইত্যাদি), তারপর আপনি আবশ্যক হিসাবে পাস SqlDbType.VarChar। যথাযথ 8 বা 16-বিট এসকিউএল সার্ভার ডেটাটাইপের সাথে ঘোষিত এনকোডিংটি মেলে ফেলতে ব্যর্থ হওয়ার ফলে আপনি যে "এনকোডিংটি স্যুইচ করতে অক্ষম" ত্রুটি হয়ে উঠবে।

উদাহরণস্বরূপ, আপনার StringWriterভিত্তিক সিরিয়ালাইজ কোডটি ব্যবহার করে , আমি কেবল এক্সএমএলের ফলাফলযুক্ত স্ট্রিংটি প্রিন্ট করেছি এবং এটি এসএসএমএসে ব্যবহার করেছি। আপনি নীচে দেখতে পারেন, এক্সএমএল ঘোষণা অন্তর্ভুক্ত করা হয়েছে (কারণStringWriter একটি বিকল্প নেই OmitXmlDeclarationমত XmlWriter, যা যতদিন আপনি সঠিক SQL সার্ভার ডাটাটাইপ হিসাবে স্ট্রিং পাস কোন সমস্যা ভঙ্গি করে):

-- Upper-case "N" prefix == NVARCHAR, hence no error:
DECLARE @Xml XML = N'<?xml version="1.0" encoding="utf-16"?>
<string>Test ሴ😸</string>';
SELECT @Xml;
-- <string>Test ሴ😸</string>

আপনি দেখতে পাচ্ছেন, এটি মানক ASCII এর বাইরেও অক্ষরগুলি পরিচালনা করে হল বিএমপি কোড পয়েন্ট ইউ + 1234 এবং 😸এটি পরিপূরক চরিত্রের কোড পয়েন্ট ইউ + 1F638। তবে, নিম্নলিখিত:

-- No upper-case "N" prefix on the string literal, hence VARCHAR:
DECLARE @Xml XML = '<?xml version="1.0" encoding="utf-16"?>
<string>Test ሴ😸</string>';

নিম্নলিখিত ত্রুটির ফলাফল:

Msg 9402, Level 16, State 1, Line XXXXX
XML parsing: line 1, character 39, unable to switch the encoding

তবে, সমস্ত ব্যাখ্যা একদিকে রেখে আপনার মূল প্রশ্নের সম্পূর্ণ সমাধান:

আপনি স্পষ্টভাবে হিসাবে স্ট্রিং পাস SqlDbType.VarChar। সুইচSqlDbType.NVarChar এবং এটি এক্সএমএল ঘোষণাটি সরানোর অতিরিক্ত পদক্ষেপের প্রয়োজন ছাড়াই কাজ করবে। এটি SqlDbType.VarCharএক্সএমএল ঘোষণা রাখার এবং অপসারণের চেয়ে বেশি পছন্দ করা হয় কারণ এক্সএমএল অ-মানক-এএসসিআইআই অক্ষর অন্তর্ভুক্ত করা হলে এই সমাধানটি ডেটা ক্ষতি রোধ করবে। উদাহরণ স্বরূপ:

-- No upper-case "N" prefix on the string literal == VARCHAR, and no XML declaration:
DECLARE @Xml2 XML = '<string>Test ሴ😸</string>';
SELECT @Xml2;
-- <string>Test ???</string>

আপনি দেখতে পাচ্ছেন, এবার কোনও ত্রুটি নেই তবে এখন ডেটা-লোকসান 🙀


আমি মনে করি যে আমি এই অতি-জটিল জটিলতার কারণ ছিলাম, কারণ মূলত আমার একটিতে দুটি প্রশ্ন ছিল। আমি আপনার সংক্ষিপ্ত উত্তরটি সত্যিই পছন্দ করি এবং এটি পরবর্তী সময় চেষ্টা করে দেখতে হবে ডিবিতে এক্সএমএল সংরক্ষণ করতে। সুতরাং যদি আমি এই অধিকারটি দেখতে পাই: আপনি এক্সএমএলকে ডিবিতে সঞ্চয় করে চ্যালেঞ্জগুলি ব্যাখ্যা করেছেন। এক্স স্কিমেল (ইউটিএফ -16 ব্যতীত) কাজ করার সময় স্ট্রিং রাইটার ব্যবহার করে জোন স্কিট সংক্ষিপ্তসার জানায় এবং খ্রিস্টান হাইটার কেবল এটির সাথে কাজ করার একটি দুর্দান্ত উপায় সরবরাহ করে।
স্ট্যাম্পেডএক্সভি

@ স্ট্যাম্পেডিএক্সভি আমি আমার উত্তর আপডেট করেছি (পয়েন্টগুলি আরও ভালভাবে বোঝানোর জন্য স্পষ্টতা + নতুন স্টাফের জন্য কয়েকটি পরিবর্তন)। আশা করি এটি এখন আরও স্পষ্ট হয়েছে যে এই দুটি উত্তরই নিজের পক্ষে ভাল, আপনার প্রশ্নের উত্তর দেওয়ার জন্য এগুলি কোনওভাবেই প্রয়োজনীয় নয়। তারা সি # / .NET এ এক্সএমএল সিরিয়ালাইজেশন নিয়ে কাজ করে তবে এই প্রশ্নটি এসকিউএল সার্ভারে এক্সএমএল সংরক্ষণ করার বিষয়ে। তারা এমন তথ্য সরবরাহ করে যা জেনে রাখা ভাল এবং আপনি প্রাথমিকভাবে সরবরাহ করা থেকে ভাল কোড হতে পারে তবে তাদের (বা অন্য কেউ এখানে নেই) সত্যই বিষয়বস্তুতে নয়। তবে এটি সঠিকভাবে নথিভুক্ত জিনিস নয়, তাই বিভ্রান্তি।
সলোমন রুটজকি

@ স্ট্যাম্পেডিএক্সভি কি আমার সংশোধনগুলি বোঝায়? আমি কেবল শীর্ষে একটি সংক্ষিপ্ত বিভাগ যুক্ত করেছি যা পরিষ্কার হতে পারে। দীর্ঘ গল্প সংক্ষিপ্ত: যদি না অন্য কিছু ঘটে থাকে যা আপনি প্রশ্নের বিবরণটিতে অন্তর্ভুক্ত না করেন, তবে মনে হচ্ছে আপনার কোডটি 99% সঠিক ছিল এবং সম্ভবত একটি একক আপার কেস যুক্ত করে সংশোধন করা যেতে পারে " এন "। কোনও বিশেষ এনকোডিং স্টাফের প্রয়োজন নেই, এবং খ্রিস্টান কোডটি দুর্দান্ত, তবে আমার পরীক্ষায় দেখা যাচ্ছে যে এটি এক্সএমএল ঘোষণার পরে কোনও সিআরএলএফ রাখে ব্যতীত এটি আপনার ২ য় কোড ব্লকের অনুরূপ সিরিয়ালাইজেশন ফিরিয়ে দেয়। আমি বাজি ধরেছি আপনি SqlDbType.NVarCharবা পরিবর্তন হয়েছে Xml
সলোমন রুটজকি

এখনও এটি নিজে যাচাই করার জন্য সময় বের করার চেষ্টা করছি। এটি অবশ্যই ভাল এবং যৌক্তিক মনে হয় তবে এটি নিশ্চিত নয় যে কোনও গ্রহণযোগ্য উত্তর পরিবর্তন করার পক্ষে এটি যথেষ্ট।
স্ট্যাম্পেডিএক্সভি

218

এর মধ্যে একটি সমস্যা StringWriterহ'ল ডিফল্টরূপে এটি আপনাকে যে এনকোডিংটি বিজ্ঞাপন দেয় সেটি সেট করতে দেয় না - যাতে আপনি কোনও এক্সএমএল ডকুমেন্টটি ইউটিএফ -১ as এর এনকোডিংয়ের বিজ্ঞাপন দিয়ে শেষ করতে পারেন, যার অর্থ এটি আপনাকে ইউটিএফ -16 হিসাবে এনকোড করা দরকার যদি আপনি এটি একটি ফাইল লিখুন। এতে সাহায্য করার জন্য আমার একটি ছোট ক্লাস রয়েছে যদিও:

public sealed class StringWriterWithEncoding : StringWriter
{
    public override Encoding Encoding { get; }

    public StringWriterWithEncoding (Encoding encoding)
    {
        Encoding = encoding;
    }    
}

বা আপনার যদি কেবল ইউটিএফ -8 প্রয়োজন হয় (যা আমার প্রায়শই প্রয়োজন):

public sealed class Utf8StringWriter : StringWriter
{
    public override Encoding Encoding => Encoding.UTF8;
}

আপনি কেন আপনার এক্সএমএলটিকে ডাটাবেসে সংরক্ষণ করতে পারেন নি - আপনি চেষ্টা করার সময় কী ঘটেছিল সে সম্পর্কে আপনাকে আমাদের আরও বিশদ দিতে হবে, আপনি যদি চান আমাদের এটি নির্ণয় / সংশোধন করতে সক্ষম হও


আমি এখন ডাটাবেস সমস্যার আরও বিশদ মধ্যে গিয়েছিলাম। প্রশ্ন দেখুন।
স্ট্যাম্পেডএক্সভি

4
দু: খজনকভাবে StringWriterএনকোডিংটি বিবেচনায় নেই, তবে কম নয়, একটি নিফটি সামান্য পদ্ধতির জন্য ধন্যবাদ :)
চৌ

4
এবং "এক্সএমএল পার্সিং: লাইন 1, চরিত্র 38, এনকোডিং স্যুইচ করতে অক্ষম" দ্বারা সমাধান করা যেতে পারে "; settings.OmitXmlDeclaration = মিথ্যা settings.Indent = FALSE"
MGE

আমি সাধারণত সঠিক এনকোডিং সহ একটি MemoryStreamএবং একটি ব্যবহার করে এটিকে ঘিরে StreamWriterStreamWriter হয় একটি TextWriter(টাইপ যা XmlWriter.Createআশা) স্বনির্ধারিত এনকোডিং এর সাথে, সব পরে।
নাইয়ারগডস

4
@ নাইয়ারগডস: সুতরাং এই ধরণের জিনিস দিয়ে একটি নিউজ প্যাকেজ তৈরি করুন, তারপরে এটি পাওয়া সর্বদা সহজ। আমি বরং কোডের পঠনযোগ্যতার সাথে আপস করার চেয়ে এটি করতাম যা মূলত অন্য কিছু প্রয়োজনীয়তার বিষয়ে।
জন স্কিটি

126

একটি XML ডকুমেন্টটিকে .NET স্ট্রিংয়ে সিরিয়াল করার সময়, এনকোডিংটি অবশ্যই ইউটিএফ -16 এ সেট করতে হবে। স্ট্রিংগুলি ইউটিএফ -16 হিসাবে অভ্যন্তরীণভাবে সংরক্ষণ করা হয়, সুতরাং এটি কেবলমাত্র এনকোডিংটিই তা বোঝায়। আপনি যদি কোনও আলাদা এনকোডিংয়ে ডেটা সঞ্চয় করতে চান তবে আপনি পরিবর্তে একটি বাইট অ্যারে ব্যবহার করুন।

এসকিউএল সার্ভার একই ধরণের নীতিতে কাজ করে; কোন স্ট্রিং একটি মধ্যে পাসxml কলামে অবশ্যই ইউটিএফ -16 হিসাবে এনকোড করা উচিত। এসকিউএল সার্ভার এমন কোনও স্ট্রিং প্রত্যাখ্যান করবে যেখানে এক্সএমএল ঘোষণাটি ইউটিএফ -16 নির্দিষ্ট করে না। যদি এক্সএমএল ঘোষণাটি উপস্থিত না থাকে, তবে এক্সএমএল স্ট্যান্ডার্ডের এটি ইউটিএফ -8 এ ডিফল্ট হওয়া আবশ্যক, সুতরাং এসকিউএল সার্ভার এটিও প্রত্যাখ্যান করবে।

এটি মাথায় রেখে, রূপান্তরটি করার জন্য এখানে কয়েকটি ইউটিলিটি পদ্ধতি রয়েছে।

public static string Serialize<T>(T value) {

    if(value == null) {
        return null;
    }

    XmlSerializer serializer = new XmlSerializer(typeof(T));

    XmlWriterSettings settings = new XmlWriterSettings()
    {
        Encoding = new UnicodeEncoding(false, false), // no BOM in a .NET string
        Indent = false,
        OmitXmlDeclaration = false
    };

    using(StringWriter textWriter = new StringWriter()) {
        using(XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings)) {
            serializer.Serialize(xmlWriter, value);
        }
        return textWriter.ToString();
    }
}

public static T Deserialize<T>(string xml) {

    if(string.IsNullOrEmpty(xml)) {
        return default(T);
    }

    XmlSerializer serializer = new XmlSerializer(typeof(T));

    XmlReaderSettings settings = new XmlReaderSettings();
    // No settings need modifying here

    using(StringReader textReader = new StringReader(xml)) {
        using(XmlReader xmlReader = XmlReader.Create(textReader, settings)) {
            return (T) serializer.Deserialize(xmlReader);
        }
    }
}

প্রশ্ন সংযোজন দেখুন। আমি আমার পরীক্ষার ফলাফলগুলি বুঝতে পারি না, এটি আপনার বক্তব্যের বিরোধিতা করে বলে মনে হচ্ছে যে ডিজি সর্বদা ইউটিএফ -16 চায় / নেয় / গ্রহণ করে।
স্ট্যাম্পেডএক্সভি

9
আপনাকে ইউটিএফ -16 হিসাবে এনকোড করতে হবে না - তবে আপনাকে অবশ্যই নিশ্চিত করতে হবে যে আপনি যে এনকোডিংটি ব্যবহার করছেন সেটি StringWriterপ্রত্যাশার সাথে মিলে। আমার উত্তর দেখুন। অভ্যন্তরীণ স্টোরেজ ফর্ম্যাটটি এখানে অপ্রাসঙ্গিক।
জন স্কিটি

ঠিক আছে যে আমি বুঝতে পেরেছি। আমার নতুন উদাহরণে: এনকোডিং সম্পূর্ণরূপে ছাড়ার ফলে ডিবি নিজেই সিদ্ধান্ত নিতে পারে কোন এনকোডিংটি ব্যবহৃত হয়েছিল - এটি কেন কাজ করেছে তা ঠিক। আমি কি এখনই এটি বুঝতে পারি?
স্ট্যাম্পেডিএক্সভি

4
@ স্টেভিসি: দুঃখিত, আমার ভুল আমি ভিবি থেকে কোডটি হাতে-রূপান্তর করেছিলাম, যা Nothingকোনও প্রকারে স্পষ্টত রূপান্তরযোগ্য। আমি Deserializeকোড সংশোধন করেছি । Serializeসাবধানবাণী একটি Resharper শুধুমাত্র জিনিস, তার নিজস্ব অবজেক্ট করে না কম্পাইলার হতে হবে এবং তা বৈধ।
খ্রিস্টান হাইটার

4
জন স্কিটির মন্তব্যটি প্রসারিত করার জন্য, না, ইউটিএফ -16 প্রয়োজন হয় না। এটি প্রমাণ করার জন্য একটি দৃ concrete উদাহরণের জন্য দয়া করে stackoverflow.com/a/8998183/751158 দেখুন
জিৎসেমার

20

প্রথমত, পুরানো উদাহরণগুলি সন্ধান করা থেকে সাবধান থাকুন। আপনি এমন একটি ব্যবহার করেছেন XmlTextWriterযা ব্যবহার করে , যা .NET 2.0 হিসাবে অবমানিত। XmlWriter.Createপরিবর্তে ব্যবহার করা উচিত।

একটি এক্সএমএল কলামে কোনও বস্তুকে সিরিয়ালাইজ করার উদাহরণ এখানে রয়েছে:

public void SerializeToXmlColumn(object obj)
{
    using (var outputStream = new MemoryStream())
    {
        using (var writer = XmlWriter.Create(outputStream))
        {
            var serializer = new XmlSerializer(obj.GetType());
            serializer.Serialize(writer, obj);
        }

        outputStream.Position = 0;
        using (var conn = new SqlConnection(Settings.Default.ConnectionString))
        {
            conn.Open();

            const string INSERT_COMMAND = @"INSERT INTO XmlStore (Data) VALUES (@Data)";
            using (var cmd = new SqlCommand(INSERT_COMMAND, conn))
            {
                using (var reader = XmlReader.Create(outputStream))
                {
                    var xml = new SqlXml(reader);

                    cmd.Parameters.Clear();
                    cmd.Parameters.AddWithValue("@Data", xml);
                    cmd.ExecuteNonQuery();
                }
            }
        }
    }
}

4
আমি কেবল এটি একবারেই ভোট দিতে পারি তবে এটি এখানে শীর্ষস্থানীয় উত্তর পাওয়ার যোগ্য। শেষ পর্যন্ত, কোনও এনকোডিং ঘোষিত বা ব্যবহৃত হয়েছে তা যতক্ষণ যায় XmlReaderতা পার্স করা যায় না e এটি ডাটাবেসে প্রি-পার্সড প্রেরণ করা হবে এবং তারপরে ডিবি-কে অক্ষর এনকোডিংগুলি সম্পর্কে কিছু জানতে হবে না - ইউটিএফ -16 বা অন্যথায়। বিশেষত, দ্রষ্টব্য যে এক্সএমএল ঘোষণাগুলি ডাটাবেসে থাকা ডেটা দিয়েও অবিচল থাকে না, এটি প্রবেশের জন্য কোন পদ্ধতি ব্যবহার করা হয় তা নির্বিশেষে। এখানে এবং অন্য কোথাও অন্যান্য উত্তরে যেমন দেখানো হয়েছে দয়া করে অতিরিক্ত রূপান্তরগুলির মাধ্যমে এক্সএমএল চালিয়ে অপচয় করবেন না।
ziesemer

1
public static T DeserializeFromXml<T>(string xml)
{
    T result;
    XmlSerializerFactory serializerFactory = new XmlSerializerFactory();
    XmlSerializer serializer =serializerFactory.CreateSerializer(typeof(T));

    using (StringReader sr3 = new StringReader(xml))
    {
        XmlReaderSettings settings = new XmlReaderSettings()
        {
            CheckCharacters = false // default value is true;
        };

        using (XmlReader xr3 = XmlTextReader.Create(sr3, settings))
        {
            result = (T)serializer.Deserialize(xr3);
        }
    }

    return result;
}

-1

এটি অন্য কোথাও আচ্ছাদিত হয়ে থাকতে পারে তবে এক্সএমএল উত্সের এনকোডিং লাইনটি 'utf-16' এ পরিবর্তন করা হলে এক্সএমএলকে একটি এসকিউএল সার্ভারের এক্সএমএল'ডাটা টাইপের ভিতরে প্রবেশ করতে দেয়।

using (DataSetTableAdapters.SQSTableAdapter tbl_SQS = new DataSetTableAdapters.SQSTableAdapter())
{
    try
    {
        bodyXML = @"<?xml version="1.0" encoding="UTF-8" standalone="yes"?><test></test>";
        bodyXMLutf16 = bodyXML.Replace("UTF-8", "UTF-16");
        tbl_SQS.Insert(messageID, receiptHandle, md5OfBody, bodyXMLutf16, sourceType);
    }
    catch (System.Data.SqlClient.SqlException ex)
    {
        Console.WriteLine(ex.Message);
        Console.ReadLine();
    }
}

ফলস্বরূপ সমস্ত এক্সএমএল পাঠ্য 'xML' ডেটা টাইপ ক্ষেত্রে fieldোকানো হয় তবে 'শিরোনাম' লাইনটি সরিয়ে ফেলা হয়। ফলাফলের রেকর্ডে আপনি যা দেখছেন তা ঠিক just

<test></test>

"জবাব দেওয়া" এন্ট্রিটিতে বর্ণিত সিরিয়ালাইজেশন পদ্ধতিটি লক্ষ্য ক্ষেত্রে মূল শিরোনামকে অন্তর্ভুক্ত করার একটি উপায় তবে ফলাফলটি হল যে বাকী এক্সএমএল পাঠ্যটি একটি এক্সএমএলে আবদ্ধ থাকে <string></string> ট্যাগে ।

কোডের টেবিল অ্যাডাপ্টারটি ভিজ্যুয়াল স্টুডিও 2013 ব্যবহার করে স্বয়ংক্রিয়ভাবে নির্মিত একটি শ্রেণি "" নতুন ডেটা উত্স যুক্ত করুন: উইজার্ড।


4
প্রতিস্থাপন? এই অত্যধিক হাসিখুশি.
মিলিগ্রামবার্টিজ

4
সিরিয়াসলি - এটি করবেন না। কখনও। যদি আমি আমার এক্সএমএলতে "ইউটিএফ -8" উল্লেখ করা কিছু গদ্য অন্তর্ভুক্ত করতে চাইতাম - আপনি কেবল আমার ডেটা এমন কিছুতে পরিবর্তন করেছেন যা আমি বলি নি!
টিম আবেল

4
কোডটিতে একটি ভুল নির্দেশ করার জন্য ধন্যবাদ। বডিএক্সএমএল পরিবর্তে ("ইউটিএফ -8", "ইউটিএফ -16") এর পরিবর্তে এমন কোড থাকা উচিত যা এক্সএমএল শিরোনামকে ইউটিএফ -8 ইউটিএফ -16 এ পরিবর্তন করে। আমি যে বিষয়টি সত্যই উল্লেখ করতে চাইছিলাম তা হল উত্স এক্সএমএল-এর শিরোনামে এই পরিবর্তনটি করা, তারপরে এক্সএমএলটির বডিটি কোনও এক্সএমএল ডেটা টাইপ ক্ষেত্রটি ব্যবহার করে একটি এসকিউএল টেবিল রেকর্ডে প্রবেশ করা যায় এবং শিরোনামটি সরিয়ে ফেলা হয়। যে কারণে আমি এখন মনে করি না (চার বছর আগে!) ফলাফলটি তখন কার্যকর কিছু ছিল। এবং হ্যাঁ, 'প্রতিস্থাপন' ব্যবহার করে বোবা ভুল। এটা হয়।
ডিএলজি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.