我使用XmlSerializer
将class
输出到.xml
文件。在大多数情况下,这是按预期和预期工作的。但是,作为一项要求,某些字符需要从数据值中删除,并替换为正确的转义字符。
在我需要替换值的元素中,我使用Replace()
方法并返回更新后的字符串。下面的代码显示了这个字符串替换;注释掉的行是因为XmlSerializer
已经逃脱了那些特定的字符。
我要求第三方转义&
,<
,>
,'
和"
个字符。 XML元素的值。目前,字符&
,<
和>
正在通过XmlSerializer
正确转义。
存在这些字符时收到的错误是:
我们的系统在请求邮件附件中检测到潜在威胁。
但是,当我在执行字符串替换后序列化XML文档时,XmlSerializer
会看到&
中的'
字符,并使其成为&apos;
。我认为这是XmlSerializer
对象的正确功能。但是,我希望序列化器能够 a。)忽略转义字符;或 b。)序列化要逃脱的其他字符。
任何人都可以了解一下,具体来说,如何完成其中任何一项?
字符串替换方法
public static string CheckValueOfProperty(string str)
{
string trimmedString = str.Trim();
if (string.IsNullOrEmpty(trimmedString))
return null;
else
{
// Commented out because the Serializer already transforms a '&' character into the appropriate escape character.
//trimmedString = trimmedString .Replace("&", "&");
//trimmedString = trimmedString.Replace("<", "<");
//trimmedString = trimmedString.Replace(">", ">");
trimmedString = trimmedString.Replace("'", "'");
trimmedString = trimmedString.Replace("\"", """);
return trimmedString;
}
}
XmlSerializer代码
public static void SerializeAndOutput(object obj, string outputFilePath, XmlSerializerNamespaces ns = null)
{
XmlSerializer x = new XmlSerializer(obj.GetType());
// If the Output File already exists, delete it.
if (File.Exists(outputFilePath))
{
File.Delete(outputFilePath);
}
// Then, Create the Output File and Serialize the parameterized object as Xml to the Output File
using (TextWriter tw = File.CreateText(outputFilePath))
{
if (ns == null)
{
x.Serialize(tw, obj);
}
else { x.Serialize(tw, obj, ns); }
}
// =====================================================================
// The code below here is no longer needed, was used to force "utf-8" to
// UTF-8" to ensure the result was what was being expected.
// =====================================================================
// Create a new XmlDocument object, and load the contents of the OutputFile into the XmlDocument
// XmlDocument xdoc = new XmlDocument() { PreserveWhitespace = true };
// xdoc.Load(outputFilePath);
// Set the Encoding property of each XmlDeclaration in the document to "UTF-8";
// xdoc.ChildNodes.OfType<XmlDeclaration>().ToList().ForEach(d => d.Encoding = "UTF-8");
// Save the XmlDocument to the Output File Path.
// xdoc.Save(outputFilePath);
}
答案 0 :(得分:0)
在XML中的节点内容中使用时,单引号和双引号字符不需要转义。单引号或双引号字符仅在节点属性的值中使用时才需要进行转义。这就是XMLSerializer不会逃避它们的原因。你也不需要逃避它们。
请参阅this question and answer以供参考。
BTW:之后将编码设置为UTF-8的方式也很尴尬。您可以使用StreamWriter指定编码,然后XMLSerializer将自动使用该编码,并在XML声明中指定它。
答案 1 :(得分:0)
这是我提出的解决方案。我只用一个示例XML文件测试它,而不是我正在创建的实际XML文件,因此性能可能会受到影响;但是,这似乎有效。
我正在逐行读取XML文件作为字符串,并用适当的转义字符替换字符串中找到的任何已定义的“特殊”字符。它应按specialCharacterList
Dictionary<string, string>
变量的顺序处理,这意味着&
字符应首先处理。处理<
,>
和"
个字符时,它只会查看XML元素的值。
using System;
using System.Collections.Generic;
using System.IO;
namespace testSerializer
{
class Program
{
private static string filePath = AppDomain.CurrentDomain.BaseDirectory + "testFile.xml";
private static string tempFile = AppDomain.CurrentDomain.BaseDirectory + "tempFile.xml";
private static Dictionary<string, string> specialCharacterList = new Dictionary<string, string>()
{
{"&","&"}, {"<","<"}, {">",">"}, {"'","'"}, {"\"","""}
};
static void Main(string[] args)
{
ReplaceSpecialCharacters();
}
private static void ReplaceSpecialCharacters()
{
string[] allLines = File.ReadAllLines(filePath);
using (TextWriter tw = File.CreateText(tempFile))
{
foreach (string strLine in allLines)
{
string newLineString = "";
string originalString = strLine;
foreach (var item in specialCharacterList)
{
// Since these characters are all valid characters to be present in the XML,
// We need to look specifically within the VALUE of the XML Element.
if (item.Key == "\"" || item.Key == "<" || item.Key == ">")
{
// Find the ending character of the beginning XML tag.
int firstIndexOfCloseBracket = originalString.IndexOf('>');
// Find the beginning character of the ending XML tag.
int lastIndexOfOpenBracket = originalString.LastIndexOf('<');
if (lastIndexOfOpenBracket > firstIndexOfCloseBracket)
{
// Determine the length of the string between the XML tags.
int lengthOfStringBetweenBrackets = lastIndexOfOpenBracket - firstIndexOfCloseBracket;
// Retrieve the string that is between the element tags.
string valueOfElement = originalString.Substring(firstIndexOfCloseBracket + 1, lengthOfStringBetweenBrackets - 1);
newLineString = originalString.Substring(0, firstIndexOfCloseBracket + 1) + valueOfElement.Replace(item.Key, item.Value) + originalString.Substring(lastIndexOfOpenBracket);
}
}
// For the ampersand (&) and apostrophe (') characters, simply replace any found with the escape.
else
{
newLineString = originalString.Replace(item.Key, item.Value);
}
// Set the "original" string to the new version.
originalString = newLineString;
}
tw.WriteLine(newLineString);
}
}
}
}
}