我有一个小的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>
然后是数据集.ReadXml()和Update()数据集。
每当遇到错误数据时,我都会遇到以下异常:
System.Xml.Schema.XmlSchemaValidationException 没有处理
消息=“'COL1' 元素无效 - 值'A40' 根据其数据类型无效 'http://www.w3.org/2001/XMLSchema:decimal' - 字符串'A40'不是有效的十进制值。“
我可以想出解决这个问题的几种方法,但是他们都觉得有点像kludge,我想学习更优雅的东西,并提高我的知识。这是我到目前为止所提出的:
UPDATE:数据可能不好,因为它来自不验证COL1用户输入的应用程序 - 但COL2中的数字是正确计算的,而COL1应该对应不同的系统。应记录任何无效条目,以便纠正它们。在将数据写入数据库之后,另一个系统验证COL1是否有效,并且用户很快就会发现它是否在另一个系统中没有正确显示 - 他们过去常常用手加载它:)
答案 0 :(得分:3)
预处理由...提供的XML 加载到之前的Web服务 验证XML阅读器,删除任何 坏节点完全。
这是我选择的选项,它允许你在异常之前获取错误输入并将其存储在某个地方,以便稍后查看。然后你可以找到有问题的用户并使用你的另一种方法
用一个用来支持用户 大槌直到他们学会了 这是第一次
答案 1 :(得分:0)
我的问题是:你想对错误数据做什么? 你想忽略它,消毒它(从'A40'中移除'A'),或者将它收集到有一天最后显示给用户(谈到一个大槌;-)?
如果您只想遗漏任何数据不正确的行,请在执行任何其他操作之前删除有错误的行。您必须自己决定是否仍需要在将其输入数据库之前验证剩余的xml。如果以限制性方式进行剥离,则不再需要剥离。
答案 2 :(得分:0)
如果只是偶尔的话,我可能会缓存最后一次已知的好结果并完全忽略任何不良反馈。 (也许会记录警告。)我会尽量避免尝试纠正错误的Feed。如果它对模式甚至不起作用,那么谁说实际数据是正确的。
此外,您绝对应该向Feed提供商提出问题,以尝试让他们解决问题。