programing

C#의 잘못된 XML 문자 탈출

stoneblock 2023. 10. 21. 09:54

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를 사용할 것을 제안합니다.이름 인코딩 메서드입니다.작은 샘플은 다음과 같습니다.

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를 사용합니다.이스케이프

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\.@-]", ""); 

정규식 패턴 [^\w.@-]은(는) 단어 문자, 마침표, @ 기호 또는 하이픈이 아닌 문자와 일치합니다.단어 문자는 밑줄과 같은 문자, 십진 숫자 또는 구두점 연결입니다.이 패턴과 일치하는 모든 문자는 문자열로 대체됩니다.빈, 교체 패턴에 의해 정의된 문자열입니다.사용자 입력에 추가 문자를 허용하려면 정규식 패턴의 문자 클래스에 해당 문자를 추가합니다.예를 들어 정규식 패턴 [^\w]입니다.@-\%]는 또한 백분율 기호와 입력 문자열의 백슬래시를 허용합니다.

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

이 내용도 참조하십시오.

XML 이름 태그에서 잘못된 문자 제거 - RegEx C#

다음은 지정된 XML 문자열에서 문자를 제거하는 기능입니다.

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

XML 태그 내부에 사용되는 문자열에 대해 유효하지 않은 XML 문자만 탈출하는 경우 이와 같은 간단한 작업을 수행할 수 있습니다.

이것은 XML 라이브러리를 사용하지 않을 때 작동합니다.

public string EscapeXMLCharacters (string target)
{
    return
        target
            .Replace("&", "&amp;")
            .Replace("<", "&lt;")
            .Replace(">", "&gt;")
            .Replace("\"", "&quot;")
            .Replace("'", "&apos;");
}

그러면 이렇게 부를 수 있을 겁니다.

public string GetXMLBody(string content)
{
    return @"<input>" + EscapeXMLCharacters(content) + "</input>";
}
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);
}

이 간단한 방법은 잘못된 문자를 같은 값으로 바꾸지만 XML 컨텍스트에서 허용됩니다.


문자열을 쓰려면 XMLWriteStringWithout을 사용합니다.잘못된 문자(string Unfiltered String)입니다.
문자열을 읽으려면 XMLReadStringWithout을 사용합니다.잘못된 문자(string FilteredString)입니다.

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