Nice programing

C #에서 잘못된 XML 문자 이스케이프

nicepro 2020. 10. 13. 19:23
반응형

C #에서 잘못된 XML 문자 이스케이프


잘못된 XML 문자가 포함 된 문자열이 있습니다. 문자열을 구문 분석하기 전에 잘못된 XML 문자를 어떻게 이스케이프 (또는 제거) 할 수 있습니까?


잘못된 XML 문자를 제거하는 방법으로 XmlConvert.IsXmlChar 메서드 를 사용하는 것이 좋습니다 . .NET Framework 4 이후에 추가되었으며 Silverlight에서도 제공됩니다. 다음은 작은 샘플입니다.

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;
    }
}

업데이트 : 인코딩 작업이 소스 문자열의 길이보다 크거나 같은 길이의 문자열을 생성한다는 점을 언급해야합니다. 길이 제한이있는 문자열 열의 데이터베이스에 인코딩 된 문자열을 저장하고 데이터 열 제한에 맞게 앱에서 소스 문자열 길이의 유효성을 검사 할 때 중요 할 수 있습니다.


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);
  }
}

xml을 작성하는 경우 프레임 워크에서 제공하는 클래스를 사용하여 xml을 만듭니다. 탈출이나 그 어떤 것도 신경 쓰지 않아도됩니다.

Console.Write(new XElement("Data", "< > &"));

출력됩니다

<Data>&lt; &gt; &amp;</Data>

형식이 잘못된 XML 파일을 읽어야하는 경우 정규식을 사용 하지 마십시오 . 대신 Html Agility Pack을 사용하십시오 .


Irishman에서 제공하는 RemoveInvalidXmlChars 메서드는 대리 문자를 지원하지 않습니다. 테스트하려면 다음 예제를 사용하십시오.

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

    string newContent = RemoveInvalidXmlChars(content);

    Console.WriteLine(newContent);
}

이것은 빈 문자열을 반환하지만 안됩니다! 문자 U + 10330 은 유효한 XML 문자 이므로 "\ U00010330"을 반환해야 합니다.

대리 문자를 지원하려면 다음 방법을 사용하는 것이 좋습니다.

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의 최적화 된 버전입니다.이 메서드는 모든 호출에서 새 배열을 생성하지 않으므로 불필요하게 GC를 강조합니다.

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();

}

// Replace invalid characters with empty strings.
   Regex.Replace(inputString, @"[^\w\.@-]", ""); 

The regular expression pattern [^\w.@-] matches any character that is not a word character, a period, an @ symbol, or a hyphen. A word character is any letter, decimal digit, or punctuation connector such as an underscore. Any character that matches this pattern is replaced by String.Empty, which is the string defined by the replacement pattern. To allow additional characters in user input, add those characters to the character class in the regular expression pattern. For example, the regular expression pattern [^\w.@-\%] also allows a percentage symbol and a backslash in an input string.

Regex.Replace(inputString, @"[!@#$%_]", "");

Refer this too :

Removing Invalid Characters from XML Name Tag - RegEx C#

Here is a function to remove the characters from a specified XML string:

using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace XMLUtils
{
    class Standards
    {
        /// <summary>
        /// Strips non-printable ascii characters 
        /// Refer to http://www.w3.org/TR/xml11/#charsets for XML 1.1
        /// Refer to http://www.w3.org/TR/2006/REC-xml-20060816/#charsets for XML 1.0
        /// </summary>
        /// <param name="content">contents</param>
        /// <param name="XMLVersion">XML Specification to use. Can be 1.0 or 1.1</param>
        private void StripIllegalXMLChars(string tmpContents, string XMLVersion)
        {    
            string pattern = String.Empty;
            switch (XMLVersion)
            {
                case "1.0":
                    pattern = @"#x((10?|[2-F])FFF[EF]|FDD[0-9A-F]|7F|8[0-46-9A-F]9[0-9A-F])";
                    break;
                case "1.1":
                    pattern = @"#x((10?|[2-F])FFF[EF]|FDD[0-9A-F]|[19][0-9A-F]|7F|8[0-46-9A-F]|0?[1-8BCEF])";
                    break;
                default:
                    throw new Exception("Error: Invalid XML Version!");
            }

            Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
            if (regex.IsMatch(tmpContents))
            {
                tmpContents = regex.Replace(tmpContents, String.Empty);
            }
            tmpContents = string.Empty;
        }
    }
}

string XMLWriteStringWithoutIllegalCharacters(string UnfilteredString)
{
    if (UnfilteredString == null)
        return string.Empty;

    return XmlConvert.EncodeName(UnfilteredString);
}

string XMLReadStringWithoutIllegalCharacters(string FilteredString)
{
    if (UnfilteredString == null)
        return string.Empty;

    return XmlConvert.DecodeName(UnfilteredString);
}

This simple method replace the invalid characters with the same value but accepted in the XML context.


To write string use XMLWriteStringWithoutIllegalCharacters(string UnfilteredString).
To read string use XMLReadStringWithoutIllegalCharacters(string FilteredString).

참고URL : https://stackoverflow.com/questions/8331119/escape-invalid-xml-characters-in-c-sharp

반응형