【问题标题】:XDocument change schemaXDocument 更改架构
【发布时间】:2017-11-26 21:26:33
【问题描述】:

我正在开发一个带有 XSD 文件的 XML 验证器。必须使用任何 XSD 文件验证 XML,这意味着必须将 XSD 模式添加到 XML 文件中,但当然必须首先从 XML 中删除模式(如果存在)。 我的解决方法:

-我正在通过递归成功地从 XML 文件中删除架构。

-我已成功将 XSD 架构添加到 XML。

我遇到的问题是验证:

XDocument doc = XDocument.Load(filename);

/* 递归添加/删除模式 */

doc.Save("temp.xml");

using (XmlReader reader = XmlReader.Create("temp.xml", settings))
       doc = XDocument.Load(reader, LoadOptions.SetLineInfo);

我使用 XmlReader 而不是 .Validate() 方法的原因是我需要突出显示实际的错误行,而 .Validate() 方法不会从 ValidationEventHandler 异常中返回 LineNumber。

是否有另一种方法可以更改 XML 的架构,并且仍然通过行验证它而不将新的 xml 保存到临时文件?

【问题讨论】:

    标签: c# xml validation xsd linq-to-xml


    【解决方案1】:

    我不明白...在ValidationEventHandler 中,您会得到ValidationEventArgs,它有一个Exception 属性,带有LineNumber 和LinePosition。当然,如果您是针对架构验证,而不是检查它是否格式正确(这是 XDocument.Load() 唯一应该做的事情,AFAIK)。

    关于针对任意模式的验证:有一个extension method,添加Validate() 的重载,您可以在其中指定另一个模式。不幸的是,由于一些模糊的原因,行号信息丢失了。但是,您可以在阅读期间执行验证。首先定义您要使用的架构:

    var schemas = new XmlSchemaSet();
    schemas.Add("", XmlReader.Create(new StringReader(xmlSchema)));
    

    然后创建一个XmlReaderSettings 来应用您的架构:

    var settings = new XmlReaderSettings();
    settings.Schemas = schemas;
    settings.ValidationType = ValidationType.Schema;
    settings.ValidationEventHandler += (sender, e) => 
        Console.WriteLine($"{e.Exception.LineNumber}: {e.Message}");
    

    然后加载文档,就会有需要的信息:

    using (var reader = XmlReader.Create(stream, settings))
    {
        var doc = XDocument.Load(reader, LoadOptions.SetLineInfo);
    |
    

    【讨论】:

    • 这也可以,但问题是如果我这样验证,LineNumber 属性总是返回 0,我正在使用 SetLineInfo LoadOptions 但不起作用。
    • 让我了解一下,您使用 Load(..., LoadOptions.SetLineInfo) 加载并使用 Validate(...) 进行验证,行号始终为 0?
    • 是的,就这样。
    • 感谢您的帮助。结果发现根本不需要添加/删除模式。
    • 好的,我明白你的意思。好吧,只需在加载过程中移动验证。正在更新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 2017-11-08
    • 2021-01-22
    • 2011-01-01
    相关资源
    最近更新 更多