我可以让XmlTextWriter写<element/>而不是<element />吗?
我遇到了一种情况,XML数据正在通过两种不同的方式进行处理。在一个地方,我使用Python的xml.dom.minidom库来处理。在另一个地方,则是在.NET中通过XmlTextWriter进行类似的处理。
在Python代码生成的输出中,空元素的写法是<ElementName/>(元素关闭前没有空格)。而在.NET代码中,插入了一个空格(变成了<ElementName />)。这对XML的有效性或含义没有任何影响,但在比较这两种输出时,会被检测为不同。
有没有办法告诉XmlTextWriter不要加这个多余的空格?如果不行,有没有办法在Python生成的输出中加上这个空格(除了修改库的源代码,虽然可以,但我觉得这样做不太好;-))?
更新:也许我应该解释一下我真正想做的,而不是只描述问题。可能我把事情搞得比应该的更复杂/痛苦了。
我真正需要的是一种机制来确定XML表示的结构没有被修改。我最开始是把XML扁平化(这样在.NET环境中处理时就消除了空格问题),然后计算数据的一个合适的哈希值。有没有更好的机制我可以/应该使用?
5 个回答
我会在输出结果出来后再进行处理,做一些查找和替换,而不是去修改这个库的内容。
你会发现,只有当你把 XmlWriterSettings
中的 Indent
属性设置为 true
时,问题才会出现。当 Indent == false
时,就不会插入空格。但如果你想要缩进,就得接受这个空格。
所以,也许解决你程序的问题就是在两个工具中都关闭缩进?
这有点遗憾,因为几乎可以改变这种行为。
XmlWriter
的实现实际上是调用 XmlWriterSettings.CreateWriter
来根据你传入的设置创建一个写入器。如果 Indent == true
,那么它会创建一个 XmlEncodedRawTextWriterIndent
,这是一个内部类,继承自抽象类 XmlWriter
。它重写了 WriteFullEndElement
方法,并插入了那个空格。
理论上,你可以创建一个自己的类,继承自 XmlEncodedRawTextWriterIndent
,并重写 WriteFullEndElement
。如果能做到这一点,就可以轻松防止缩进。但你无法这样做,因为它是一个 internal
类(只在 System.Xml
内部可用)。即使你能子类化 XmlEncodedRawTextWriterIndent
,你也会遇到问题,因为 XmlWriterSettings.CreateXmlWriter
没有办法实例化你的类,而 XmlWriterSettings
是 sealed
的。
我想,阻止创建自定义 XmlWriter
类是有充分理由的,尽管我现在想不起来是什么原因。
可能这不是你想要的答案:不要把XML输出当作纯文本来比较。我们在单元测试中这样做(两个通过XML消息通信的应用),结果很脆弱,容易出错,麻烦,而且需要很多维护。你应该解析XML输出,比较它的结构。虽然写这样一个工具可能需要更多的工作(也许已经有现成的工具了),但当任何库的下一个版本输出稍微改变时,它仍然可以正常工作。
编辑:好吧,现在你更详细地解释了你的问题,让我看看我是否理解正确:你有一些数据要生成XML输出。有时是通过.NET,有时是通过Python。假设你通过.NET生成输出,然后计算一个哈希值并存储它。后来你通过Python生成输出,内容应该是相同的,你也计算一个哈希值。结果这两个哈希值不相等,因为空格的问题。
如果是这样的话,你可以遍历XML文档,根据看到的节点及其属性和值来计算哈希值。一个更简单的方法是去掉输出中所有不相关的空格(无论输出来自哪里),然后再进行哈希计算。你可以在Python中做到这一点;)