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("<", "&lt;");
        //trimmedString = trimmedString.Replace(">", "&gt;");

        trimmedString = trimmedString.Replace("'", "&apos;");
        trimmedString = trimmedString.Replace("\"", "&quot;");

        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>()
        {
            {"&","&amp;"}, {"<","&lt;"}, {">","&gt;"}, {"'","&apos;"}, {"\"","&quot;"}
        };

        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=新词典()
{
{“&”,“&;},{”