【问题标题】:right approach to handling bad xml data处理不良 xml 数据的正确方法
【发布时间】:2010-09-20 00:49:03
【问题描述】:

我有一个小的 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()ing 数据集。

每当遇到错误数据时,我都会收到以下异常:

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

【问题讨论】:

    标签: c# xml xsd xmlreader xmlschemaset


    【解决方案1】:

    预处理由 加载到 验证 XML 阅读器,删除任何 完全坏节点。

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

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

    【讨论】:

    • 这只是一个临时解决方法,直到我弄清楚喷水系统的 API
    【解决方案2】:

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

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

    【讨论】:

    • 我已经稍微澄清了这个问题。我开始认为预处理 xml 可能是答案。
    【解决方案3】:

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

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

    【讨论】:

    • 它的提要本身还不错; COL1 中的数据偶尔会输入错误,但除非提醒用户,否则不会更正,并且在此之前可以多次更新 COL2。而且我不确定非验证应用程序的供应商是否仍然存在:(
    猜你喜欢
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2010-12-08
    • 2011-02-28
    • 2016-01-15
    • 1970-01-01
    • 2016-05-02
    相关资源
    最近更新 更多