我有一个小的 c# windows 服务,它定期从 web 服务中提取 xml 并将数据存储在数据库表中。
不幸的是,它失败了,因为 Web 服务中偶尔会有错误的数据——字符串而不是小数。我对 Web 服务没有任何控制权(来自我们无法更改的软件的未经验证的用户输入),但我想记录错误数据以便重新输入。
这是看起来像这样的简单数据:
<ROWS>
<ROW>
<COL1>5405</COL1>
<COL2>102.24</COL1>
</ROW>
<ROW>
<COL1>5406</COL1>
<COL2>2.25</COL1>
</ROW>
</ROWS>
该表只有两列,COL1 (NUMBER, 10)、COL2 (NUMBER, 10,2)。
我正在使用验证 XmlReader 和这个 XSD:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ROWS" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="ROWS" msdata:IsDataSet="true" msdata:Locale="en-US">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="ROW">
<xs:complexType>
<xs:sequence>
<xs:element name="COL1" type="xs:decimal" minOccurs="0" />
<xs:element name="COL2" type="xs:decimal" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
然后是 dataset.ReadXml() 和 Update() 数据集。
每当遇到错误数据时,我都会收到以下异常:
System.Xml.Schema.XmlSchemaValidationException 未处理
Message="'COL1' 元素无效 - 根据其数据类型,值 'A40' 无效' http://www.w3.org/2001/XMLSchema:decimal ' - 字符串 'A40' 不是有效的十进制价值。”
我可以想出几种解决问题的方法,但它们都感觉有点笨拙,我想学习一些更优雅的东西,并提高我的知识。到目前为止,这是我想出的:
- 在加载到验证 XML 阅读器之前预处理 Web 服务提供的 XML,完全删除任何坏节点。
- 捕获 XmlSchemaValidationExceptions 并尝试从它们优雅地继续(不确定那个)
- 不要使用验证 XML 阅读器,而是在将未经验证的 xml 加载到数据集时捕获异常。(再次不确定)
- 在数据集中有字符串列,并忽略错误数据,直到我更新它,并捕获数据库拒绝的任何内容。
- 去用大槌站在用户面前,直到他们学会第一次做对(太耗时)
- 别的东西?
更新:数据可能很糟糕,因为它来自不验证 COL1 的用户输入的应用程序 - 但 COL2 中的数字计算正确,并且 COL1 应该对应于不同的系统。应记录任何无效条目,以便更正。数据写入数据库后,另一个系统会验证 COL1 是否有效,如果它在另一个系统中没有正确显示,用户很快就会发现 - 他们过去常常手动加载它:)