C# System.Xml.Serialization - 仅使用 <a></a> 而从不使用 <a/>

C# System.Xml.Serialization - use only <a></a> and never <a/>

我的客户遇到了一个奇怪的问题 - 我正在使用 XmlSerializer 阅读一个 XML 文档(实际上是一个 InfoPath 文档),修改它,然后写出一个 XML 文档使用XmlSerializer,然后使用XmlTextWriter添加一些处理指令。一切正常,生成的文档实际上完全 XML 符合并且可以被 InfoPath 读取。然而,结构中发生的一个变化是原始文档的所有空标签都以 <A></A> 的形式写入,而当我的文档写入时,它变成了 <A/>。由于 XML 标准,实际上完全相同。但是,我的客户(一家大公司)显然有一些 check/validation 硬编码 <A></A> 脚本,但它们失败了。他现在心烦意乱,懒得改剧本了,想要 <A></A> 符号!我如何设置 XmlTextWriter 来做到这一点?

老实说,我认为如果您要使用内置的序列化程序,那么您最好使用 find/replace。看起来你不能覆盖标签的实际形式,至少我还没有看到一种方法来做到这一点,甚至覆盖了一些方法。

因此,我会检查是否有标签为空,输入 "[[[EMPTYVALUE]]]" 这样的值,这样你就可以得到

<A>[[[EMPTYVALUE]]]</A>

然后生成你的XML,在保存XML文件之前,将其转换为字符串,并用"<A></A>"

替换"<A>[[[EMPTYVALUE]]]</A>"

您可以只对 <A/> 进行替换,但我认为创建一个更大的字符串来替换更安全。

您可以通过为 XmlSerializer 提供您自己的 XmlWriter 后代来做到这一点,这将覆盖 WriteEndElement method。默认情况下,此方法根据正在输出的元素的内容生成一个空元素 (<a />) 或一个结束元素 (</a>)。您可以更改行为以始终生成完整的结束元素。

public class MyXmlWriter : XmlTextWriter
{
    // …constructors etc. omitted for the sake of simplicity…

    public override void WriteEndElement()
    {
        // this should do the trick
        WriteFullEndElement();
    }
}

但是,还需要做一些工作,例如这个方法的Async版本,但原则上应该很容易像上面那样实现。我建议查看 XmlTextWriter.WriteEndElementthe source code 并推导出一个更适合您情况的版本。