C# XmlSerializer转义添加的转义字符
我正在使用C# XmlSerializer转义添加的转义字符,c#,xmlserializer,C#,Xmlserializer,我正在使用XmlSerializer将类输出到.xml文件。在大多数情况下,这是预期和预期的工作。但是,作为一项要求,某些字符需要从数据的值中删除,并替换为其正确的转义字符 在需要替换中的值的元素中,我使用replace()方法并返回更新的字符串。下面的代码显示了这个字符串替换;注释掉的行是因为XmlSerializer已经转义了这些特定字符 我需要第三方转义&,,'和“字符,当它们出现在XML元素的值中时。目前,字符&,正通过XmlSerializer进行适当转义 出现这些字符时收到的错误为:
XmlSerializer
将类
输出到.xml
文件。在大多数情况下,这是预期和预期的工作。但是,作为一项要求,某些字符需要从数据的值中删除,并替换为其正确的转义字符
在需要替换中的值的元素中,我使用replace()
方法并返回更新的字符串。下面的代码显示了这个字符串替换;注释掉的行是因为XmlSerializer
已经转义了这些特定字符
我需要第三方转义&
,
,'
和“
字符,当它们出现在XML元素的值中时。目前,字符&
,
正通过XmlSerializer
进行适当转义
出现这些字符时收到的错误为:
我们的系统在请求消息附件中检测到潜在威胁
但是,当我在执行字符串替换后序列化XML文档时,XmlSerializer
会看到
中的&
字符,并使其成为'
。我认为这是XmlSerializer
对象的正确功能。但是,我希望序列化程序)忽略转义字符;或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;
}
}
公共静态字符串CheckValueOfProperty(字符串str)
{
string trimmedString=str.Trim();
if(string.IsNullOrEmpty(trimmedString))
返回null;
其他的
{
//注释掉,因为序列化程序已将“&”字符转换为相应的转义字符。
//trimmedString=trimmedString。替换(“&”、“&;”);
//trimmedString=trimmedString.Replace(“,”);
trimmedString=trimmedString.Replace(“'”,“&apos;”);
trimmedString=trimmedString。替换(“\”,“”);
返回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);
}
public静态void SerializeAndOutput(对象对象obj,字符串outputFilePath,xmlsializernamespaces ns=null)
{
XmlSerializer x=新的XmlSerializer(obj.GetType());
//如果输出文件已存在,请将其删除。
if(File.Exists(outputFilePath))
{
File.Delete(outputFilePath);
}
//然后,创建输出文件并将参数化对象作为Xml序列化到输出文件
使用(TextWriter tw=File.CreateText(outputFilePath))
{
如果(ns==null)
{
x、 序列化(tw,obj);
}
else{x.Serialize(tw,obj,ns);}
}
// =====================================================================
//下面的代码不再需要,它被用来强制“utf-8”使用
//UTF-8“以确保结果符合预期。
// =====================================================================
//创建一个新的XmlDocument对象,并将OutputFile的内容加载到XmlDocument中
//XmlDocument xdoc=newxmldocument(){PreserveWhitespace=true};
//加载(outputFilePath);
//将文档中每个XmlDeclaration的编码属性设置为“UTF-8”;
//xdoc.ChildNodes.OfType().ToList().ForEach(d=>d.Encoding=“UTF-8”);
//将XmlDocument保存到输出文件路径。
//保存(outputFilePath);
}
在XML中的节点内容中使用单引号和双引号字符时,不需要转义。单引号或双引号字符仅在节点属性的值中使用时需要转义。这就是XMLSerializer没有逃避它们的原因。你也不需要逃避它们
请参阅以供参考
顺便说一句:之后将编码设置为UTF-8的方式也很尴尬。您可以使用StreamWriter指定编码,然后XMLSerializer将自动使用该编码,并在XML声明中指定该编码。在XML中的节点内容中使用单引号和双引号字符时,无需转义。单引号或双引号字符仅在节点属性的值中使用时需要转义。这就是XMLSerializer没有逃避它们的原因。你也不需要逃避它们 请参阅以供参考
顺便说一句:之后将编码设置为UTF-8的方式也很尴尬。您可以使用StreamWriter指定编码,然后XMLSerializer将自动使用该编码,并在XML声明中指定它。以下是我提出的解决方案。我只是用一个示例XML文件测试了它,而不是我正在创建的实际XML文件,所以性能可能会受到影响;然而,这似乎是可行的 我以字符串的形式逐行读取XML文件,并将字符串中定义的任何“特殊”字符替换为相应的转义字符。它应该按照
特殊字符列表
字典
变量的顺序处理,这意味着和
字符应该首先处理。当处理
和“
字符时,它将只查看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);
}
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
命名空间测试序列化程序
{
班级计划
{
私有静态字符串filePath=AppDomain.CurrentDomain.BaseDirectory+“testFile.xml”;
私有静态字符串tempFile=AppDomain.CurrentDomain.BaseDirectory+“tempFile.xml”;
专用静态词典specialCharacterList=新词典()
{
{“&”,“&;},{”