c# - सी#में अवैध एक्सएमएल अक्षर से बचें




.net xml (4)

मेरे पास एक स्ट्रिंग है जिसमें अमान्य XML वर्ण हैं। स्ट्रिंग को पार्स करने से पहले मैं अवैध XML वर्णों से कैसे बच सकता हूं (या हटा सकता हूं)?


अमान्य XML वर्णों को हटाने का तरीका मैं आपको XmlConvert.IsXmlChar विधि का उपयोग करने का सुझाव देता हूं। इसे .NET Framework 4 के बाद जोड़ा गया था और सिल्वरलाइट में भी प्रस्तुत किया गया है। यहां छोटा नमूना है:

void Main() {
    string content = "\v\f\0";
    Console.WriteLine(IsValidXmlString(content)); // False

    content = RemoveInvalidXmlChars(content);
    Console.WriteLine(IsValidXmlString(content)); // True
}

static string RemoveInvalidXmlChars(string text) {
    var validXmlChars = text.Where(ch => XmlConvert.IsXmlChar(ch)).ToArray();
    return new string(validXmlChars);
}

static bool IsValidXmlString(string text) {
    try {
        XmlConvert.VerifyXmlChars(text);
        return true;
    } catch {
        return false;
    }
}

और अमान्य XML वर्णों से बचने के तरीके के रूप में मैं आपको XmlConvert.EncodeName विधि का उपयोग करने का सुझाव देता हूं। यहां छोटा नमूना है:

void Main() {
    const string content = "\v\f\0";
    Console.WriteLine(IsValidXmlString(content)); // False

    string encoded = XmlConvert.EncodeName(content);
    Console.WriteLine(IsValidXmlString(encoded)); // True

    string decoded = XmlConvert.DecodeName(encoded);
    Console.WriteLine(content == decoded); // True
}

static bool IsValidXmlString(string text) {
    try {
        XmlConvert.VerifyXmlChars(text);
        return true;
    } catch {
        return false;
    }
}

अद्यतन: यह उल्लेख किया जाना चाहिए कि एन्कोडिंग ऑपरेशन एक स्ट्रिंग को लंबाई के साथ उत्पन्न करता है जो स्रोत स्ट्रिंग की लंबाई से अधिक या बराबर होता है। यह महत्वपूर्ण हो सकता है जब आप लंबाई सीमा वाले स्ट्रिंग कॉलम में किसी डेटाबेस में एन्कोडेड स्ट्रिंग को संग्रहीत करते हैं और डेटा कॉलम सीमा फिट करने के लिए अपने ऐप में स्रोत स्ट्रिंग लंबाई मान्य करते हैं।


आयरिशमैन द्वारा प्रदान की गई RemoveInvalidXmlChars विधि सरोगेट वर्णों का समर्थन नहीं करती है। इसका परीक्षण करने के लिए, निम्न उदाहरण का उपयोग करें:

static void Main()
{
    const string content = "\v\U00010330";

    string newContent = RemoveInvalidXmlChars(content);

    Console.WriteLine(newContent);
}

यह एक खाली स्ट्रिंग देता है लेकिन यह नहीं होना चाहिए! इसे "\ U00010330" वापस करना चाहिए क्योंकि चरित्र U+10330 एक वैध एक्सएमएल चरित्र है।

सरोगेट पात्रों का समर्थन करने के लिए, मैं निम्नलिखित विधि का उपयोग करने का सुझाव देता हूं:

public static string RemoveInvalidXmlChars(string text)
{
    if (string.IsNullOrEmpty(text))
        return text;

    int length = text.Length;
    StringBuilder stringBuilder = new StringBuilder(length);

    for (int i = 0; i < length; ++i)
    {
        if (XmlConvert.IsXmlChar(text[i]))
        {
            stringBuilder.Append(text[i]);
        }
        else if (i + 1 < length && XmlConvert.IsXmlSurrogatePair(text[i + 1], text[i]))
        {
            stringBuilder.Append(text[i]);
            stringBuilder.Append(text[i + 1]);
            ++i;
        }
    }

    return stringBuilder.ToString();
}

यहां उपर्युक्त विधि RemoveInvalidXmlChars का एक अनुकूलित संस्करण है जो प्रत्येक कॉल पर एक नई सरणी नहीं बनाता है, इस प्रकार जीसी को अनजाने में जोर देता है:

public static string RemoveInvalidXmlChars(string text)
    {
        if (text == null) return text;
        if (text.Length == 0) return text;

        // a bit complicated, but avoids memory usage if not necessary
        StringBuilder result = null;
        for (int i = 0; i < text.Length; i++)
        {
            var ch = text[i];
            if (XmlConvert.IsXmlChar(ch))
            {
                result?.Append(ch);
            }
            else
            {
                if (result == null)
                {
                    result = new StringBuilder();
                    result.Append(text.Substring(0, i));
                }
            }
        }

        if (result == null)
            return text; // no invalid xml chars detected - return original text
        else
            return result.ToString();

    }

SecurityElement.Escape उपयोग करें

using System;
using System.Security;

class Sample {
  static void Main() {
    string text = "Escape characters : < > & \" \'";
    string xmlText = SecurityElement.Escape(text);
//output:
//Escape characters : &lt; &gt; &amp; &quot; &apos;
    Console.WriteLine(xmlText);
  }
}







escaping