繁体   English   中英

使用 XDocument.Validate 验证 Xml 架构时,XmlSchemaValidationException.LineNumber 和 LinePosition 为 0

[英]XmlSchemaValidationException.LineNumber and LinePosition are 0 when validating an Xml Schema with XDocument.Validate

我正在尝试使用带有 XDocument.Validate 扩展方法的 Xml 架构来验证 Xml 片段。 每当使用无效的 Xml 片段时,ValidationEventHandler 都会正确触发,但是 XmlSchemaValidationException 的 LineNumber 和 LinePosition 属性均为 0。

private bool Validate(XDocument doc)
{
    bool isValid = true;
    List<string> validationErrors = new List<string>();

    XmlSchemaSet schemas = new XmlSchemaSet();
    schemas.Add(null, "MyCustomSchema.xsd");

    doc.Validate(schemas, (sender, args) =>
    {
        validationErrors.Add(String.Format("{0}: {1} [Ln {2} Col {3}]", 
            args.Severity, 
            args.Exception.Message, 
            args.Exception.LineNumber, 
            args.Exception.LinePosition));

        isValid = false;
    }, false);

    return isValid;
}

我在上面的例子中的目标是使用 validationErrors 来通知用户验证失败的原因。 但是,使用此方法时,LineNumber 和 LinePosition 均为 0。

该片段看起来很简单,并且在验证有效和无效的 Xml 片段方面似乎按预期工作。

提前致谢!

您不再验证Xml的文本表示,而是验证对象模型。 结果是没有行和位置,因为内存中没有文件,只有XElement,XAttribute等对象。 另一个有用的提示是问自己-如果在加载XDocument之后但运行验证之前修改(例如添加了Elelment)XDocument,应该返回什么行和位置? 如果您不创建或修改Xml,最快的方法是使用XmlReader来验证您的Xml文档。 另外,如果输入是文件或流,则应该获取行和位置信息,以防发生验证错误。

在您的ValidationEventHandlersender实现IXmlLineInfo接口,该接口包含成员System.Xml.IXmlLineInfo.LineNumberSystem.Xml.IXmlLineInfo.LinePosition

因此,您可以这样做:

doc.Validate(schemas, (sender, args) =>
{
    var lineInfo = sender as IXmlLineInfo;
    validationErrors.Add(String.Format("{0}: {1} [Ln {2} Col {3}]",
        args.Severity,
        args.Exception.Message,
        lineInfo?.LineNumber,
        lineInfo?.LinePosition));

    isValid = false;
}, false);

这是一个老问题,但这里有一种在创建 XDocument 实例时保留位置的方法 - 确保使用LoadOptions.SetLineInfo

XDocument.Parse(xml, LoadOptions.SetLineInfo);

然后您可以在 Validate 方法中提取位置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM