Eingebaute .NET-Escaper wie z.B. SecurityElement.Escape
auch nicht richtig entkommen/abstreifen.
- Sie könnten
CheckCharacters
a false
sowohl für den Schreiber als auch für den Leser, wenn Ihre Anwendung die einzige ist, die mit der Datei interagiert. Die resultierende XML-Datei wäre technisch gesehen immer noch ungültig Allerdings.
Siehe:
XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.Encoding = new UTF8Encoding(false);
xmlWriterSettings.CheckCharacters = false;
var sb = new StringBuilder();
var w = XmlWriter.Create(sb, xmlWriterSettings);
w.WriteStartDocument();
w.WriteStartElement("Test");
w.WriteString("hello \xb world");
w.WriteEndElement();
w.WriteEndDocument();
w.Close();
var xml = sb.ToString();
- Wenn die Einstellung
CheckCharacters
a true
(die es standardmäßig ist) ist ein bisschen zu streng, da es einfach eine Ausnahme werfen wird eine alternative Annäherung, die mehr Milde zu ungültigen XML-Zeichen ist, wäre, sie einfach zu entfernen:
Ein wenig Googeln ergab die Whitelist XmlTextEncoder wird jedoch auch entfernt DEL
und andere im Bereich U+007F-U+0084, U+0086-U+009F, die nach der Gültige XML-Zeichen auf Wikipedia sind nur in bestimmten Kontexten gültig und werden im RFC als entmutigte, aber dennoch gültige Zeichen erwähnt.
public static class XmlTextExtentions
{
private static readonly Dictionary<char, string> textEntities = new Dictionary<char, string> {
{ '&', "&"}, { '<', "<" }, { '>', ">" },
{ '"', """ }, { '\'', "'" }
};
public static string ToValidXmlString(this string str)
{
var stripped = str
.Select((c,i) => new
{
c1 = c,
c2 = i + 1 < str.Length ? str[i+1]: default(char),
v = XmlConvert.IsXmlChar(c),
p = i + 1 < str.Length ? XmlConvert.IsXmlSurrogatePair(str[i + 1], c) : false,
pp = i > 0 ? XmlConvert.IsXmlSurrogatePair(c, str[i - 1]) : false
})
.Aggregate("", (s, c) => {
if (c.pp)
return s;
if (textEntities.ContainsKey(c.c1))
s += textEntities[c.c1];
else if (c.v)
s += c.c1.ToString();
else if (c.p)
s += c.c1.ToString() + c.c2.ToString();
return s;
});
return stripped;
}
}
Dieser Test besteht alle XmlTextEncoder-Tests mit Ausnahme desjenigen, der erwartet, dass er DEL
die XmlConvert.IsXmlChar
, Wikipedia, und die Spezifikation kennzeichnet es als gültiges (wenn auch entmutigtes) Zeichen.