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.WriteEndElement
的 the source code 并推导出一个更适合您情况的版本。
我的客户遇到了一个奇怪的问题 - 我正在使用 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.WriteEndElement
的 the source code 并推导出一个更适合您情况的版本。