如何在子类中处理XmlWriter.Create

时间:2019-06-25 10:15:43

标签: c# xml xmlwriter

我需要为我的项目更改XmlWriter的行为,以更改对空xml元素进行序列化的方式。目前,我的代码像这样使用XmlWriter和XmlSerializer:

public string Serialize(object o)
{
    XmlWriterSettings settings = new XmlWriterSettings();
    ...

    StringWriter stringWriter = new StringWriter();

    XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings);
    XmlSerializer serializer = new XmlSerializer(o.GetType());
    serializer.Serialize(xmlWriter, o);

    return stringWriter.ToString();
}

序列化我的xml时,会将空元素序列化为<emptyElement/>,但是我需要xml来将空元素序列化为<emptyElement></emptyElement>。我为此找到的最佳解决方案是在多年前的一个Microsoft论坛上提出的:https://social.msdn.microsoft.com/Forums/en-US/979315cf-6727-4979-a554-316218ab8b24/xml-serialize-empty-elements?forum=xmlandnetfx

  

更快,更安全的方法是编写自己的XmlWriter子类并将其提供给XmlSerializer。

     

YourXmlWriter将聚合标准1,并将所有WriteEndElement()调用转换为WriteFullEndElement()调用。

我尝试编写自己的XmlWriter子类,覆盖了我需要覆盖的两个方法:

public abstract class CustomXmlWriter : XmlWriter
    {
        public override void WriteEndElement()
        {
            WriteFullEndElement();
        }

        public override Task WriteEndElementAsync()
        {
            return WriteFullEndElementAsync();
        }
    }

理论上,我认为这应该可行。但是,在尝试使用代码时,我遇到了XmlWriter.Create周围的砖墙。由于明显的原因,我无法将生成的XmlWriter强制转换为我的CustomXmlWriter,并且由于该方法是静态方法,因此无法覆盖该方法。

我该如何处理静态Create方法?我可以想到的唯一另一种方法是取消我自己的CustomXmlWriter的想法,并在方法末尾简单地操作字符串,但这感觉很不对劲。我不知道我要实现的目标是否可行,或者是否有一个似乎无法在任何地方找到的简单设置。

1 个答案:

答案 0 :(得分:1)

尝试使用Regex作为临时修复程序。输入的变量可以是整个xml字符串,它将替换每次出现的情况。 :

        static void Main(string[] args)
        {

            string input = "<emptyElement/>";
            string patternNullTag = @"\<(?'tagname'\w+)/\>";
            string output = Regex.Replace(input, patternNullTag, ReplaceNullElement);
        }
        static string ReplaceNullElement(Match match)
        {
            string tagname = match.Value.Replace("<", "").Replace("/>", "");
            string newElement = "<" + tagname + ">" + "</" + tagname + ">";
            return newElement;
        }