2

我有一个小的 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 是否有效,如果它在另一个系统中没有正确显示,用户很快就会发现 - 他们过去常常手动加载它:)

4

3 回答 3

3

在加载到验证 XML 阅读器之前预处理 Web 服务提供的 XML,完全删除任何坏节点。

这是我会选择的选项,它允许您在异常之前获取错误输入并将其存储在某个地方以便以后查看。然后你可以找到有问题的用户并使用你的另一种方法

去用大槌站在用户面前,直到他们学会第一次做对

于 2008-10-30T16:39:51.617 回答
0

我的问题是:你想用错误的数据做什么?您是想忽略它,对其进行消毒(从“A40”中删除“A”),还是将其收集到最终向用户展示(说到大槌;-)?

如果您只想删除任何包含错误数据的行,请在执行其他任何操作之前先删除有错误的行。您必须自己决定是否仍需要在将剩余的 xml 输入数据库之前对其进行验证。如果您以限制性方式进行剥离,则不再需要。

于 2008-10-30T16:45:07.470 回答
0

如果只是偶尔,我可能会缓存最后一个已知的好结果并完全忽略任何不好的提要。(可能会记录警告。)我会尽量避免尝试纠正错误的提要。如果它甚至对架构无效,谁说实际数据是正确的。

此外,您绝对应该向提要提供商提出问题,以尝试让他们纠正问题。

于 2008-10-30T16:46:18.390 回答