इकाइयों को तकनीकी रूप से एक्सएमएल में "संख्यात्मक चरित्र संदर्भ" कहा जाता है, और जब मूल दस्तावेज़ XDocument
में लोड किया जाता है तो उन्हें हल किया जाता है। यह आपकी समस्या को सुलझाने में समस्याग्रस्त बनाता है, क्योंकि XDocument
लोड होने के बाद असामान्य सफेद जगह (आमतौर पर सादे-पाठ दर्शकों के लिए XML दस्तावेज़ों को स्वरूपित करने के लिए उपयोग किया जाता है) से हल किए गए व्हाइटस्पेस इकाइयों को अलग करने का कोई तरीका नहीं है। इस प्रकार, नीचे केवल तभी लागू होता है जब आपके दस्तावेज़ में कोई महत्वहीन व्हाइटस्पेस न हो।
System.Xml
पुस्तकालय एक Entitize
को XmlWriterSettings
वर्ग के NewLineHandling
संपत्ति की स्थापना द्वारा खाली स्थान के संस्थाओं को संरक्षित करने की अनुमति देता है। हालांकि, टेक्स्ट नोड्स के भीतर, यह केवल \r
से 
पर, और \n
से 

को अधिकृत करेगा।
सबसे आसान समाधान XmlWriter
कक्षा से प्राप्त करना है और अपने WriteString
विधि को ओवरराइड करना है ताकि वे अपने संख्यात्मक चरित्र इकाइयों के साथ व्हाइटस्पेस वर्णों को मैन्युअल रूप से प्रतिस्थापित कर सकें। WriteString
विधि को भी जगह है जहां नेट entitizes अक्षर हैं जो इस तरह के वाक्य रचना मार्करों &
, <
, और >
, जो क्रमशः &
, <
, और >
को entitized कर रहे हैं के रूप में पाठ नोड्स, में प्रदर्शित करने की अनुमति नहीं है होता है।
XmlWriter
अमूर्त है, इसलिए हम पूर्व वर्ग के सभी अमूर्त तरीकों को लागू करने से बचने के लिए XmlTextWriter
से प्राप्त करेंगे।
public class EntitizingXmlWriter : XmlTextWriter
{
public EntitizingXmlWriter(TextWriter writer) :
base(writer)
{ }
public override void WriteString(string text)
{
foreach (char c in text)
{
switch (c)
{
case '\r':
case '\n':
case '\t':
base.WriteCharEntity(c);
break;
default:
base.WriteString(c.ToString());
break;
}
}
}
}
तो उत्पादन परिवेश में उपयोग के लिए, आप, c.ToString()
भाग को खत्म करना चाहते हैं, क्योंकि यह बहुत अक्षम है: यहाँ एक त्वरित और गंदा कार्यान्वयन है। आप मूल text
के सबस्ट्रिंग्स को बैच करके कोड को अनुकूलित कर सकते हैं जिसमें आपके द्वारा अधिकृत किए जाने वाले पात्रों में से कोई भी शामिल नहीं है, और उन्हें एक साथ base.WriteString
कॉल में फ़ीड करना शामिल है।
चेतावनी का एक शब्द: निम्नलिखित अनुभवहीन कार्यान्वयन काम नहीं करेगा, आधार के बाद से WriteString
विधि &
के साथ किसी भी &
पात्रों की जगह लेंगे, जिससे \r
के कारण &#xA;
करने के लिए विस्तारित किया जाना है।
public override void WriteString(string text)
{
text = text.Replace("\r", "
");
text = text.Replace("\n", "
");
text = text.Replace("\t", "	");
base.WriteString(text);
}
अंत में, एक गंतव्य फ़ाइल या धारा में अपने XDocument
को बचाने के लिए, बस निम्नलिखित स्निपेट का उपयोग करें:
using (var textWriter = new StreamWriter(destination))
using (var xmlWriter = new EntitizingXmlWriter(textWriter))
document.Save(xmlWriter);
आशा इस मदद करता है!
संपादित:
public override void WriteString(string text)
{
// The start index of the next substring containing only non-entitized characters.
int start = 0;
// The index of the current character being checked.
for (int curr = 0; curr < text.Length; ++curr)
{
// Check whether the current character should be entitized.
char chr = text[curr];
if (chr == '\r' || chr == '\n' || chr == '\t')
{
// Write the previous substring of non-entitized characters.
if (start < curr)
base.WriteString(text.Substring(start, curr - start));
// Write current character, entitized.
base.WriteCharEntity(chr);
// Next substring of non-entitized characters tentatively starts
// immediately beyond current character.
start = curr + 1;
}
}
// Write the trailing substring of non-entitized characters.
if (start < text.Length)
base.WriteString(text.Substring(start, text.Length - start));
}
बदलते हैं जब आप पुराने दस्तावेज़ को लोड करते हैं या जब आप नया सहेजते हैं? –
@ अर्नोल्ड: जब मैं नया सहेजता हूं। – mahdaeng
आदर्श समाधान आपके एक्सएमएल के उपभोक्ता को ठीक करना होगा, ताकि यह एक्सएमएल को सही तरीके से संभाल सके। – svick