स्ट्रिंग XML में भागने


90

क्या कोई C # फ़ंक्शन है जो एक स्ट्रिंग से बचने और अन-एस्केप करने के लिए उपयोग किया जा सकता है, जिसका उपयोग किसी XML तत्व की सामग्री को भरने के लिए किया जा सकता है?

मैं VSTS 2008 + C # + .Net 3.0 का उपयोग कर रहा हूं।

संपादित करें 1: मैं सरल और कम एक्सएमएल फ़ाइल श्रृंखलाबद्ध रहा हूँ और मैं क्रमबद्धता का उपयोग नहीं करते, तो मैं स्पष्ट रूप से हाथ से एक्सएमएल चरित्र से बचने के लिए, उदाहरण के लिए, मैं लगाने की जरूरत की जरूरत a<bमें <foo></foo>, तो मैं स्ट्रिंग से बचने की जरूरत है a<bऔर यह तत्व foo में डाल दिया।


एक ही रास्ता नहीं है, लेकिन यहाँ कुछ हैं: http://weblogs.sqlteam.com/mladenp/archive/2008/10/21/Different-ways-how-to-escape-an-XML-string-in-C .aspx
मार्च

15
: कम से कम मैं के बारे में सोच सकते हैंnew XText(unescaped).ToString()
sehe

3
किसी और को इस पर ठोकर खाने के लिए, मैंने इसे सबसे अच्छा जवाब पाया है: stackoverflow.com/a/5304827/1224069
फिलिप पिटल

जवाबों:


74
public static string XmlEscape(string unescaped)
{
    XmlDocument doc = new XmlDocument();
    XmlNode node = doc.CreateElement("root");
    node.InnerText = unescaped;
    return node.InnerXml;
}

public static string XmlUnescape(string escaped)
{
    XmlDocument doc = new XmlDocument();
    XmlNode node = doc.CreateElement("root");
    node.InnerXml = escaped;
    return node.InnerText;
}

5
आपको तत्व को दस्तावेज़ में संलग्न करने की भी आवश्यकता नहीं है। हालांकि, मैं अभी भी कहूंगा कि यह पहली बार में ऐसा करने की कोशिश नहीं करना है - ऐसा लगता है कि जॉर्ज हाथ से काम करके खुद के लिए काम कर रहा है ...
जॉन स्कीट

15
मैं वास्तव में इस जवाब को नापसंद करता हूं क्योंकि यह बहुत भारी है। असली काम करने के लिए XmlDocument XmlReader / XmlWriter का उपयोग करने जा रहा है, तो क्यों पीछा करने के लिए कटौती न करें और उस भारी डोम से बचें?
स्टीवन सुदित

7
@Will, ओपी ने एक फ़ंक्शन के लिए कहा जो एक पाठ से बच जाएगा जिसे एक्सएमएल तत्व में रखा जा सकता है और विशेषता नहीं। मेरा कार्य एकल या दोहरे उद्धरणों से बच नहीं सकता क्योंकि उन्हें XML तत्वों में रखा जा सकता है।
डारिन दिमित्रोव

5
@darin अच्छा बिंदु, और एक है कि जोर दिया जाना चाहिए। मैं इस बातचीत के परिणाम से संतुष्ट हूं, और अपने आरक्षण को वापस लेता हूं। शुभ दिवस गुरूजी।

1
मुझे आश्चर्य है कि अगर HttpUtility.HtmlEncodeसे System.Webसुरक्षित रूप से इस्तेमाल किया जा सकता है?
Pooven

126

8
यह उत्तर चयनित उत्तर के विपरीत उद्धरण से बच जाता है।

1
यह जवाब seem
Haacked

16
और आप अन-एस्केप कैसे हैं?
गोंडी

2
यह उत्तर अधूरा है। यह केवल आधे प्रश्न का उत्तर देता है।
ब्रायन वेबस्टर

1
उपरोक्त टिप्पणियों से सहमत - अपूर्ण और 100% सटीक नहीं।
जी स्टोयनेव

38

संपादित करें: आप कहते हैं कि "मैं सरल और छोटी XML फ़ाइल को संक्षिप्त कर रहा हूं और मैं क्रमांकन का उपयोग नहीं करता हूं, इसलिए मुझे XML वर्ण को स्पष्ट रूप से हाथ से भागने की आवश्यकता है"।

मैं आपको दृढ़ता से सलाह दूंगा कि आप इसे हाथ से न करें। XML APIs का उपयोग आप सभी के लिए करें - मूल फ़ाइलों में पढ़ें, दोनों को एक ही दस्तावेज़ में मर्ज करें हालांकि आपको (आप शायद उपयोग करना चाहते हैं XmlDocument.ImportNode), और फिर इसे फिर से लिखें। आप अपने स्वयं के XML पार्सर / फ़ॉर्मेटर्स नहीं लिखना चाहते हैं। सीरियलाइजेशन कुछ हद तक अप्रासंगिक है।

यदि आप हमें एक छोटा लेकिन पूर्ण उदाहरण दे सकते हैं कि आप क्या करने की कोशिश कर रहे हैं, तो संभवत: हम आपको पहले स्थान पर भागने की चिंता से बचने में मदद कर सकते हैं।


मूल उत्तर

यह पूरी तरह से स्पष्ट नहीं है कि आपका क्या मतलब है, लेकिन आम तौर पर XML एपीआई आपके लिए ऐसा करते हैं। आप पाठ को एक नोड में सेट करते हैं, और यह स्वचालित रूप से उस चीज़ से बच जाएगा जो इसे करने की आवश्यकता है। उदाहरण के लिए:

LINQ to XML उदाहरण:

using System;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        XElement element = new XElement("tag",
                                        "Brackets & stuff <>");

        Console.WriteLine(element);
    }
}

डोम उदाहरण:

using System;
using System.Xml;

class Test
{
    static void Main()
    {
        XmlDocument doc = new XmlDocument();
        XmlElement element = doc.CreateElement("tag");
        element.InnerText = "Brackets & stuff <>";
        Console.WriteLine(element.OuterXml);
    }
}

दोनों उदाहरणों से आउटपुट:

<tag>Brackets &amp; stuff &lt;&gt;</tag>

यह मानते हुए कि आप XML से बचना चाहते हैं, बिल्कुल। यदि आप नहीं हैं, तो कृपया अधिक विवरण पोस्ट करें।


धन्यवाद जॉन, मैंने अपने मूल पोस्ट EDIT 1 सेक्शन में अधिक जानकारी दी है। सराहना करें यदि आप मुझे कुछ टिप्पणी और सलाह दे सकते हैं। :-)
जॉर्ज 2

"एक्सएमएल भागने के बाद" - आपका मतलब है? क्या आप कुछ अन्य शब्दों में बोल सकते हैं? हिन्दी मेरी मातृभाषा नहीं है। :-)
जॉर्ज 2

हाय जॉन, एक्सएमएल प्रारूप से सामान्य स्ट्रिंग प्रारूप में, यानी "ब्रैकेट & amp; सामान & lt; & gt;" से अन-एस्केप कैसे करें, हमें आउटपुट "ब्रैकेट और सामान <>" मिलता है।
जॉर्ज 2

2
@ जॉर्ज 2: आप XElement से इसकी वैल्यू, या XmlElement को इसके इनर टेक्स्ट के लिए पूछते हैं।
जॉन स्कीट

25

एक पंक्ति से बचने के लिए @sehe को धन्यवाद:

var escaped = new System.Xml.Linq.XText(unescaped).ToString();

मैं इसमें एक-लाइन संयुक्त राष्ट्र से बच निकलता हूं:

var unescapedAgain = System.Xml.XmlReader.Create(new StringReader("<r>" + escaped + "</r>")).ReadElementString();

XText उद्धरण से बच नहीं है।
मर्ट गुल्सोइ

9

जॉर्ज, यह आसान है। XML को संभालने के लिए हमेशा XML API का उपयोग करें। वे आपके लिए तमाम पलायन और अनादर करते हैं।

तार जोड़कर XML कभी न बनाएं।


शब्दों से जीने के लिए। कई XML एपीआई विकल्प उपलब्ध हैं, लेकिन एक चीज जिस पर हम सभी को सहमत होना चाहिए, वह यह है कि मैन्युअल स्ट्रिंग कॉन्सेप्टेशन स्वीकार्य नहीं है।
स्टीवन सुदित

जबकि मैं आम तौर पर इस बात से सहमत हूं, कुछ बहुत ही दुर्लभ मामले हो सकते हैं जहां मैनुअल भागने आवश्यक हो सकता है। उदाहरण के लिए, रोसलिन का उपयोग करते हुए XML दस्तावेज बनाते समय।
'15:56

@svick: XML को LINQ का उपयोग करके XML क्यों न बनाएं, और फिर .ToString () का उपयोग करें?
जॉन सॉन्डर्स

@ जॉनसनर्स, क्योंकि रोजलिन के पास एक्सएमएल कक्षाओं का अपना सेट है, जैसे XmlElementSyntax। और यह इस तथ्य से भी जटिल है कि आपको ///भी उत्पन्न करने की आवश्यकता है। और मैं प्रत्येक पंक्ति को एक अलग के रूप में उत्पन्न नहीं कर सकता XObject, क्योंकि यह बहुभाषी टैग के लिए काम नहीं करेगा।
svick

1
@ शविक: तो xml उत्पन्न करें, सभी एक पंक्ति में, इसके ///सामने छड़ी , फिर कोड को पुन: स्वरूपित करें। बहुत बड़ा सौदा नहीं है, और निश्चित रूप से बहुत ज्यादा कोने वाला मामला है। यदि पूरी तरह से आवश्यक हो, तो मुझे यकीन है कि आप XmlWriterलाइन ब्रेक करने के लिए एक कस्टम बना सकते हैं और जिस तरह से चाहें, वैसे ही व्हाट्सएप कर सकते हैं, लेकिन ///नई लाइनों के सामने रखकर । वैकल्पिक रूप से, XML को प्रिंट करने के लिए एक XSLT का उपयोग करें। लेकिन किसी भी स्थिति में, XML को अभी भी XML API द्वारा जेनरेट किया जाना चाहिए।
जॉन सॉन्डर्स

5

और अगर आप चाहें, तो मेरे जैसे जब मुझे यह सवाल मिला, तो XML नोड नामों से बचने के लिए, उदाहरण के लिए, जब एक्सएमएल क्रमांकन से पढ़ते हैं, तो सबसे आसान तरीका उपयोग करें:

XmlConvert.EncodeName(string nameToEscape)

यह एक्सएमएल तत्वों के लिए रिक्त स्थान और किसी भी गैर-वैध वर्ण से भी बच जाएगा।

http://msdn.microsoft.com/en-us/library/system.security.securityelement.escape%28VS.80%29.aspx


मुझे लगता है, सवालों के आधार पर, कि वे सिर्फ आंतरिक पाठ चाहते हैं। आपका समाधान काम करेंगे, लेकिन कुछ हद तक overkill के रूप में यह भी तत्व और विशेषता नाम जैसी चीजों को संभाल करने के उद्देश्य से है। \
शॉन दुग्गन

खैर मैं यहाँ नोड नामों से बचने की कोशिश कर रहा था और मुझे लगा कि मेरे निष्कर्ष भविष्य में किसी की भी मदद कर सकते हैं। मैं यह भी नहीं देखता कि "ओवरकिल" क्या है, लेकिन यह ठीक है। ;)
चार्लीब्रॉन

ओह, यह उपयोगी जानकारी है। :) मुझे लगा कि मैं यह बताऊंगा कि जिन कारणों से आपने उत्थान नहीं किया होगा उनमें से एक यह था कि लोगों को लग सकता है कि आप सवाल का जवाब नहीं दे रहे हैं।
शॉन दुग्गन

लिंक SecurityElement.Escape (स्ट्रिंग) के लिए डॉक्स की ओर जाता है, क्या यह जानबूझकर था? XmlConvert.EncodeName (स्ट्रिंग) का अपना पृष्ठ है। मुझे पता है कि यह पूछे जाने के बाद से कुछ साल हो गए हैं, लेकिन मुझे कैसे पता चलेगा कि किसका उपयोग करना है? क्या वे एक ही काम नहीं करते लेकिन अलग-अलग तरीकों से?
माइकल

4

चेतावनी: परिगलन

फिर भी डारिन दिमित्रोव का जवाब + System.Security.SecurityElement.Escape (स्ट्रिंग एस) पूरा नहीं है।

XML 1.1 में, सबसे सरल और सबसे सुरक्षित तरीका है कि हर किसी को एनकोड करना है।
जैसे &#09;\ t के लिए।
यह XML 1.0 में बिल्कुल समर्थित नहीं है।
एक्सएमएल 1.0 के लिए, बेस -64 के लिए एक संभावित समाधान चरित्र (एस) वाले टेक्स्ट को एनकोड करना है।

//string EncodedXml = SpecialXmlEscape("привет мир");
//Console.WriteLine(EncodedXml);
//string DecodedXml = XmlUnescape(EncodedXml);
//Console.WriteLine(DecodedXml);
public static string SpecialXmlEscape(string input)
{
    //string content = System.Xml.XmlConvert.EncodeName("\t");
    //string content = System.Security.SecurityElement.Escape("\t");
    //string strDelimiter = System.Web.HttpUtility.HtmlEncode("\t"); // XmlEscape("\t"); //XmlDecode("&#09;");
    //strDelimiter = XmlUnescape("&#59;");
    //Console.WriteLine(strDelimiter);
    //Console.WriteLine(string.Format("&#{0};", (int)';'));
    //Console.WriteLine(System.Text.Encoding.ASCII.HeaderName);
    //Console.WriteLine(System.Text.Encoding.UTF8.HeaderName);


    string strXmlText = "";

    if (string.IsNullOrEmpty(input))
        return input;


    System.Text.StringBuilder sb = new StringBuilder();

    for (int i = 0; i < input.Length; ++i)
    {
        sb.AppendFormat("&#{0};", (int)input[i]);
    }

    strXmlText = sb.ToString();
    sb.Clear();
    sb = null;

    return strXmlText;
} // End Function SpecialXmlEscape

XML 1.0:

public static string Base64Encode(string plainText)
{
    var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
    return System.Convert.ToBase64String(plainTextBytes);
}

public static string Base64Decode(string base64EncodedData)
{
    var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
    return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}

तो XML 1.1 में, आप सब कुछ कैसे बचते हैं?
फिलिप पिटल

@Philip Pittle: देखिए SpecialXmlEscape
Stefan Steiger

4

एक और जॉन स्कीट के उत्तर पर आधारित है जो टैग वापस नहीं करता है :

void Main()
{
    XmlString("Brackets & stuff <> and \"quotes\"").Dump();
}

public string XmlString(string text)
{
    return new XElement("t", text).LastNode.ToString();
} 

यह XML एनकोडेड फॉर्मेट में दिए गए मान को लौटाता है:

Brackets &amp; stuff &lt;&gt; and "quotes"

3

निम्नलिखित कार्य कार्य करेंगे। XmlDocument के खिलाफ परीक्षण नहीं किया, लेकिन मुझे लगता है कि यह बहुत तेज है।

public static string XmlEncode(string value)
{
    System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings 
    {
        ConformanceLevel = System.Xml.ConformanceLevel.Fragment
    };

    StringBuilder builder = new StringBuilder();

    using (var writer = System.Xml.XmlWriter.Create(builder, settings))
    {
        writer.WriteString(value);
    }

    return builder.ToString();
}

public static string XmlDecode(string xmlEncodedValue)
{
    System.Xml.XmlReaderSettings settings = new System.Xml.XmlReaderSettings
    {
        ConformanceLevel = System.Xml.ConformanceLevel.Fragment
    };

    using (var stringReader = new System.IO.StringReader(xmlEncodedValue))
    {
        using (var xmlReader = System.Xml.XmlReader.Create(stringReader, settings))
        {
            xmlReader.Read();
            return xmlReader.Value;
        }
    }
}

3

विकल्प के रूप में तीसरे पक्ष के पुस्तकालय ( न्यूटनसॉफ्ट.जॉन ) का उपयोग करना :

public static string XmlEncode(string unescaped)
{
    if (unescaped == null) return null;
    return JsonConvert.SerializeObject(unescaped); ;
}

public static string XmlDecode(string escaped)
{
    if (escaped == null) return null;
    return JsonConvert.DeserializeObject(escaped, typeof(string)).ToString();
}

उदाहरण:

a<b <==> "a&lt;b"

<foo></foo> <==> "foo&gt;&lt;/foo&gt;"

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.