Czy istnieje funkcja C #, której można użyć do zmiany znaczenia i cofnięcia zmiany znaczenia ciągu, który mógłby zostać użyty do wypełnienia zawartości elementu XML?
Używam VSTS 2008 + C # + .Net 3.0.
EDIT 1: jestem łącząc prosty i krótki plik XML i nie używam serializacji, więc trzeba jawnie uciec charakter XML ręcznie, na przykład, muszę umieścić a<b
w <foo></foo>
, więc muszę uciec ciąg a<b
i umieścić go w elemencie foo.
new XText(unescaped).ToString()
Odpowiedzi:
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; }
źródło
HttpUtility.HtmlEncode
fromSystem.Web
?SecurityElement.Escape (ciągi)
źródło
EDYCJA: Mówisz "Łączę prosty i krótki plik XML i nie używam serializacji, więc muszę jawnie ręcznie zmienić znaczenie znaków XML".
Chciałbym zdecydowanie radzimy nie robić to ręcznie. Użyj interfejsów API XML, aby zrobić to wszystko za siebie - wczytaj oryginalne pliki, połącz je w jeden dokument, jakkolwiek potrzebujesz (prawdopodobnie chcesz użyć
XmlDocument.ImportNode
), a następnie ponownie zapisz. Nie chcesz pisać własnych parserów / elementów formatujących XML. Serializacja jest tutaj nieco nieistotna.Jeśli możesz nam podać 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 interfejsy API XML robią to za Ciebie. Ustawiasz tekst w węźle, a on automatycznie zmieni wszystko, czego potrzebuje. Na przykład:
Przykład LINQ to XML:
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); } }
Dane wyjściowe z obu przykładów:
<tag>Brackets & stuff <></tag>
Oczywiście przy założeniu, że chcesz uciekać przed XML-em. Jeśli nie, prześlij więcej szczegółów.
źródło
Dzięki @sehe za jedną linię ucieczki:
var escaped = new System.Xml.Linq.XText(unescaped).ToString();
Dodaję do tego jedną linijkę un-escape:
var unescapedAgain = System.Xml.XmlReader.Create(new StringReader("<r>" + escaped + "</r>")).ReadElementString();
źródło
George, to proste. Zawsze używaj interfejsów API XML do obsługi XML. Robią dla ciebie wszystkie ucieczki i odskakiwanie.
Nigdy nie twórz kodu XML przez dołączanie ciągów.
źródło
XmlElementSyntax
. Jest to również skomplikowane przez fakt, że musisz wygenerować///
też. I nie mogę wygenerować każdego wiersza jako osobnegoXObject
, ponieważ to nie zadziała w przypadku tagów wielowierszowych.///
przed nim, a następnie sformatuj ponownie kod. Nie jest to wielka sprawa, a na pewno bardzo narożna sprawa. Jeśli jest to absolutnie konieczne, jestem pewien, że możesz utworzyć niestandardoweXmlWriter
podziały wierszy i białe znaki tak, jak chcesz, ale umieszczając je///
przed nowymi wierszami. Alternatywnie, użyj XSLT, aby dobrze wydrukować XML. Jednak w każdym przypadku XML powinien być nadal generowany przez XML API.A jeśli chcesz, tak jak ja, kiedy znalazłem to pytanie, uciec od nazw węzłów XML, jak na przykład podczas czytania z serializacji XML, użyj najprostszego sposobu:
XmlConvert.EncodeName(string nameToEscape)
Będzie również usuwał spacje i wszelkie nieprawidłowe znaki dla elementów XML.
http://msdn.microsoft.com/en-us/library/system.security.securityelement.escape%28VS.80%29.aspx
źródło
Inne ujęcie oparte na odpowiedzi Johna Skeeta, które nie zwraca tagów :
void Main() { XmlString("Brackets & stuff <> and \"quotes\"").Dump(); } public string XmlString(string text) { return new XElement("t", text).LastNode.ToString(); }
Zwraca tylko wartość przekazaną w formacie XML:
Brackets & stuff <> and "quotes"
źródło
OSTRZEŻENIE: Nekromancja
Wciąż odpowiedź Darina Dimitrova + System.Security.SecurityElement.Escape (string s) nie jest kompletna.
W XML 1.1 najprostszym i najbezpieczniejszym sposobem jest po prostu zakodowanie WSZYSTKIEGO.
Jak
	
dla \ t.Nie jest w ogóle obsługiwany w XML 1.0.
W przypadku XML 1.0 jednym możliwym obejściem jest kodowanie base-64 tekstu zawierającego znaki.
//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("	"); //strDelimiter = XmlUnescape(";"); //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); }
źródło
Następujące funkcje będą działać. Nie testowałem XmlDocument, ale myślę, że jest to znacznie 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; } } }
źródło
Korzystanie z biblioteki innej firmy ( Newtonsoft.Json ) jako alternatywy:
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<b"
<foo></foo>
<==>"foo></foo>"
źródło