0

我正在寻找在以下情况下验证大型 XML 文件的有效方法:

1) 文件从网络接收。

2) 需要根据提供的 DTD 验证 xml。

3)还有其他线程正在运行,它们将处理节点信息可配置的文件的特定节点中的数据。

4) 验证不能阻塞其他线程等待整个文件验证。

由于这是一个长时间运行的进程,xml 文件将在端口上连续接收数小时、数天或数月,中间有未知的中断。

我需要一个解决方案

1)不要让阅读器/验证器读取到文件末尾,然后发送验证结果。

2)由于Data节点包含所有数据,停止验证器到数据节点开始,开始只读取固定数量的数据,并将读取的数据发送到常设线程异步处理,让验证器继续读取和发送。

上述方法正确吗?是否存在这样的 xml 验证器?如果不是如何创建它?我尝试在一个类中继承 IXmlLineInfo、IXmlNamespaceResolver,但这似乎是实现它们的一项艰巨工作。

4

2 回答 2

1

XmlReader可以解析文件并使用XmlReaderSettings进行内联验证。

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add(null, path);
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += new System.Xml.Schema.ValidationEventHandler(ValidationEventHandler);
于 2012-08-02T11:05:29.463 回答
0

我认为可以使用 Saxon-EE 中的验证和流式处理功能(当然可以从 C# 调用)来解决这个问题,但这是一项艰巨的要求,并且产生设计超出了典型的 StackOverflow 答案的范围:它是这可以证明投资几天的咨询是合理的。

我实际上在这里考虑的是 XSD 验证而不是 DTD 验证。从您的 DTD 生成 XSD 很容易。

可能解决方案就这么简单:

<xsl:stylesheet version="3.0" ...>
<xsl:mode streamable="yes"/>

<xsl:template match="record">
  <xsl:try>
    <xsl:result-document href="{@id}.xml" validation="strict">
      <xsl:copy-of select="."/>
    </xsl:result-document>
    <xsl:catch/>
  </xsl:try>
</xsl:template>

</xsl:stylesheet>

这显然不满足您的要求的唯一部分是它全部在一个线程中运行。我们在 Saxon 中具有多线程功能,但它们不能很好地与流混合;但是,随着对要求的更详细了解,应该有解决方案。

于 2012-08-03T09:02:46.583 回答