source

XML로 문자열 이스케이프

manysource 2023. 10. 27. 22:00

XML로 문자열 이스케이프

XML 요소의 내용을 채우는 데 사용할 수 있는 문자열을 이스케이프하고 이스케이프 해제하는 데 사용할 수 있는 C# 함수가 있습니까?

저는 VSTS 2008 + C# + .Net 3.0을 사용하고 있습니다.

편집 1: 단순하고 짧은 XML 파일을 연결하고 있고 직렬화를 사용하지 않기 때문에 손으로 명시적으로 XML 문자를 탈출해야 합니다. 예를 들어 다음을 입력해야 합니다.a<b안으로<foo></foo>, 그래서 탈출 끈이 필요합니다.a<b그리고 그것을 fo 요소에 넣습니다.

보안 요소.이스케이프( 문자열)

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

편집: "간단하고 짧은 XML 파일을 연결하고 있고 직렬화를 사용하지 않으므로 손으로 명시적으로 XML 문자를 탈출해야 합니다."라고 말합니다.

손으로 하지 말 것을 강력히 권하고 싶습니다.XML API를 사용하여 모든 작업을 수행합니다. 원본 파일을 읽고 필요에 따라 두 문서를 하나의 문서로 병합합니다.XmlDocument.ImportNode), 그리고 다시 작성합니다.XML 구문 분석기/포맷을 직접 작성하고 싶지는 않을 것입니다.직렬화는 여기서는 다소 관련이 없습니다.

만약 여러분이 하려는 일을 정확하게 보여줄 수 있는 짧지만 완벽한 예를 보여준다면, 우리는 아마도 여러분이 애초에 탈출할 걱정을 하지 않아도 되도록 도울 수 있을 것입니다.


원답

무엇을 의미하는지는 정확히 알 수 없지만, 일반적으로 XML API가 이 작업을 수행합니다.노드에 텍스트를 설정하면 필요한 모든 것이 자동으로 빠져나갑니다.예를 들어,

LINQ에서 XML로의 예제:

using System;
using System.Xml.Linq;

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

        Console.WriteLine(element);
    }
}

DOM 예제:

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 탈출을 원한다는 가정입니다.그렇지 않다면 자세한 내용을 올려주시기 바랍니다.

한 줄 탈출에 대해 @sehe에게 감사드립니다.

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

여기에 한 줄짜리 탈출구를 추가합니다.

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

조지, 간단해요XML을 처리하려면 항상 XML API를 사용해야 합니다.그들은 당신을 위해 모든 탈출과 탈출을 합니다.

문자열을 추가하여 XML을 만들지 마십시오.

그리고 이 질문을 발견했을 때의 나처럼 XML 일련번호를 읽을 때처럼 XML 노드 이름을 피하기 위해서는 가장 쉬운 방법을 사용해야 합니다.

XmlConvert.EncodeName(string nameToEscape)

또한 XML 요소에 대한 공백과 유효하지 않은 문자도 피할 수 있습니다.

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

다음은 존 스키트의 답변을 바탕으로 한 것으로 태그는 반환되지 않습니다.

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"

경고: 네크로맨싱

여전히 Darin Dimitrov의 답변 + 시스템.보안.보안 요소.이스케이프( 문자열)가 완료되지 않았습니다.

XML 1.1에서 가장 간단하고 안전한 방법은 모든 것을 인코딩하는 것입니다.
맘에 들다&#09;\t에 대하여
XML 1.0에서는 전혀 지원되지 않습니다.
XML 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);
}

다음과 같은 기능이 작동합니다.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;
        }
    }
}

타사 라이브러리 사용(Newtonsoft)Json)을 대안으로:

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

public static string XmlUnescape(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;"

참고: 최신 버전에서는 위에 작성된 코드가 이스케이프와 함께 작동하지 않을 수 있으므로 문자열을 이스케이프하는 방법을 지정해야 합니다.

public static string XmlEscape(string unescaped)
{
    if (unescaped == null) return null;
    return JsonConvert.SerializeObject(unescaped, new JsonSerializerSettings()
    {
        StringEscapeHandling = StringEscapeHandling.EscapeHtml
    });
}

이스케이프 문자열의 예:

a<b==>"a\u003cb"

<foo></foo>==>"\u003cfoo\u003e\u003c/foo\u003e"

SecurityElementEscape에서 이 작업을 수행

SecurityElement에서 문자열을 사용하기 전에 문자열에서 잘못된 문자를 바꾸려면 이 메서드를 사용합니다.SecurityElement에서 잘못된 문자가 이스케이프되지 않고 사용되는 경우 인수예외가 적용됩니다.

다음 표는 잘못된 XML 문자와 해당 이스케이프된 동치 문자를 보여 줍니다.

enter image description here

https://learn.microsoft.com/en-us/dotnet/api/system.security.securityelement.escape?view=net-5.0

언급URL : https://stackoverflow.com/questions/1132494/string-escape-into-xml