String escape into XML

Czy istnieje jakaś funkcja C#, która może być używana do escape I un-escape ciągu znaków, który może być użyty do wypełnienia zawartości elementu XML?

Używam VSTS 2008 + C# +. Net 3.0.

EDIT 1: łączę prosty i krótki plik XML i nie używam serializacji, więc muszę jawnie ręcznie usuwać znak XML, na przykład muszę umieścić a<b w <foo></foo>, więc potrzebuję escape string a<b i umieścić go w elemencie foo.

Author: jessehouwing, 2009-07-15

9 answers

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;
}
 66
Author: Darin Dimitrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-20 08:28:27
 108
Author: Dana Holt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-15 17:08:16

EDIT: mówisz: "łączę prosty i krótki plik XML i nie używam serializacji, więc muszę jawnie ręcznie usuwać znak XML".

Radzę Ci nie robić tego ręcznie. Użyj interfejsów API XML, aby zrobić to wszystko za Ciebie - przeczytaj w oryginalnych plikach, połącz te dwa w jeden dokument, jednak musisz (prawdopodobnie chcesz użyć XmlDocument.ImportNode), a następnie napisz go ponownie. Nie chcesz pisać własnych parserów/formaterów XML. Serializacja jest nieco to nieistotne. Jeśli podasz nam krótki, ale kompletny przykład tego, co dokładnie próbujesz zrobić, prawdopodobnie pomożemy Ci uniknąć martwienia się o ucieczkę.

Oryginalna odpowiedź

Nie jest do końca jasne, co masz na myśli, ale zwykle API XML robią to za Ciebie. Ustawiasz tekst w węźle, a on automatycznie ucieknie od wszystkiego, czego potrzebuje. Na przykład:

LINQ to XML przykład:

using System;
using System.Xml.Linq;

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

        Console.WriteLine(element);
    }
}

Przykład 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);
    }
}

Wyjście z obu przykładów:

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

Oczywiście przy założeniu, że chcesz ucieczki XML. Jeśli nie, Napisz więcej szczegółów.

 33
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-15 16:59:42

Dzięki @sehe za jednolinijkową ucieczkę:

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

Dodaję do niego jednolinijkowy un-escape:

var unescapedAgain = System.Xml.XmlReader.Create(new StringReader("<r>" + escaped + "</r>")).ReadElementString();
 21
Author: Keith Robertson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-21 15:33:57

George, to proste. Zawsze używaj interfejsów API XML do obsługi XML. Oni wszyscy uciekają i nie uciekają dla Ciebie.

Nigdy nie twórz XML przez dodawanie łańcuchów.

 9
Author: John Saunders,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-15 17:04:38

I jeśli chcesz, tak jak ja, gdy znalazłem to pytanie, aby uniknąć nazw węzłów XML, jak na przykład podczas czytania z serializacji XML, użyj najprostszego sposobu:

XmlConvert.EncodeName(string nameToEscape)

Usunie również spacje i wszelkie Nie poprawne znaki dla elementów XML.

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

 4
Author: CharlieBrown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-29 14:35:03

WARNING: Necromancing

Nadal System odpowiedzi + Darina Dimitrowa.Ochrona.SecurityElement.Escape (string s) nie jest kompletny.

W XML 1.1 najprostszym i najbezpieczniejszym sposobem jest kodowanie wszystkiego.
Jak &#09; dla \t.
Nie jest on w ogóle obsługiwany w XML 1.0.
W XML 1.0 jednym z możliwych rozwiązań jest kodowanie tekstu zawierającego znaki (- y) w bazie base-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);
}
 3
Author: Stefan Steiger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-09 09:54:24

Następujące funkcje wykonają pracę. Nie testowałem na XmlDocument, ale myślę, że jest to o wiele szybsze.

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;
        }
    }
}
 2
Author: Ramazan Binarbasi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-21 16:00:02

Korzystanie z biblioteki innej firmy (Newtonsoft.Json ) jako alternatywa:

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

Przykład:

a<b "a&lt;b"

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

 1
Author: Los Pollos Hermanos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-12 15:24:54