处理错误的xml数据的正确方法

时间:2008-10-30 16:36:24

标签: c# xml xsd xmlreader xmlschemaset

我有一个小的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,我想学习更优雅的东西,并提高我的知识。这是我到目前为止所提出的:

  • 在加载到验证XML阅读器之前预处理Web服务提供的XML,完全删除任何坏节点。
  • 抓住XmlSchemaValidationExceptions并尝试优雅地继续它们(不确定那个)
  • 不要使用验证XML阅读器,而是在将未经验证的xml加载到数据集中时捕获异常。 (再次不确定)
  • 在数据集中包含字符串列,并在更新之前忽略错误数据,并捕获数据库拒绝的任何内容。
  • 用大号木槌支撑着用户,直到他们第一次学会正确使用它(太费时间)
  • 别的什么?

UPDATE:数据可能不好,因为它来自不验证COL1用户输入的应用程序 - 但COL2中的数字是正确计算的,而COL1应该对应不同的系统。应记录任何无效条目,以便纠正它们。在将数据写入数据库之后,另一个系统验证COL1是否有效,并且用户很快就会发现它是否在另一个系统中没有正确显示 - 他们过去常常用手加载它:)

3 个答案:

答案 0 :(得分:3)

  

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

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

  

用一个用来支持用户   大槌直到他们学会了   这是第一次

答案 1 :(得分:0)

我的问题是:你想对错误数据做什么? 你想忽略它,消毒它(从'A40'中移除'A'),或者将它收集到有一天最后显示给用户(谈到一个大槌;-)?

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

答案 2 :(得分:0)

如果只是偶尔的话,我可能会缓存最后一次已知的好结果并完全忽略任何不良反馈。 (也许会记录警告。)我会尽量避免尝试纠正错误的Feed。如果它对模式甚至不起作用,那么谁说实际数据是正确的。

此外,您绝对应该向Feed提供商提出问题,以尝试让他们解决问题。