针对在 c# 中包含和导入的 xsd 验证 xml [英] Validating xml against an xsd that has include and import in c#

查看:24
本文介绍了针对在 c# 中包含和导入的 xsd 验证 xml的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想缓存 xsd,然后针对它执行验证,而不是每次为任何 xml 加载 xsd 以提高性能.但是,我无法做到.我的猜测是编译没有添加 xsd 文件的包含和导入元素,这就是我收到以下错误的原因.

I would like to cache the xsd then perform validation against it rather than loading xsd every time for any xml in order to increase performance. However, I could not manage to do it. My guess is that the compilation does not add the include and import elements of the xsd files that is why I get the error below.

步骤如下:

首先我将 xsd 文件添加到 XmlSchemaSet

First I added the xsd file to XmlSchemaSet

public XmlSchemaSet SchemaSet;
public XmlValidator()
{
    this.SchemaSet = new XmlSchemaSet();
    using (XmlReader xsd = XmlReader.Create(xsdPath))
    {
        this.SchemaSet.Add(null, xsd);
    }
    this.SchemaSet.Compile();
}

然后我用这个XmlSchemaSet来验证xml如下:

Then I used this XmlSchemaSet to validate the xml as follows:

public void ValidateSchema(byte[] xml)
{
    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
    settings.ValidationType = ValidationType.Schema;
    settings.DtdProcessing = DtdProcessing.Parse;

    // need to add dtd first. it should not be added to the schema set above
    using (XmlReader dtd = XmlReader.Create(dtdPath, settings))
    {
        settings.Schemas.Add(null, dtd);
    }

    settings.DtdProcessing = DtdProcessing.Prohibit;
    settings.Schemas.Add(this.SchemaSet); // add the schema set

    using (MemoryStream memoryStream = new MemoryStream(xml, false))
    {
        using (XmlReader validator = XmlReader.Create(memoryStream, settings))
        {
            while (validator.Read());
        }
    }
}

注意:dtdPathxsdPath有效,输入xml有效,xsd文件有效

Notes: dtdPath, xsdPath are valid, input xml is valid, xsd files are valid

错误是:未声明http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader:StandardBusinessDocument"元素.

推荐答案

我创建了一个带有以下选项的 XmlReaderSettings:

I created a XmlReaderSettings with following options:

XmlReaderSettings settings = new XmlReaderSettings();
settings.XmlResolver = new XmlXsdResolver();     // Need this for resolving include and import
settings.ValidationType = ValidationType.Schema; // This might not be needed, I am using same settings to validate the input xml
settings.DtdProcessing = DtdProcessing.Parse;    // I have an include that is dtd. maybe I should prohibit dtd after I compile the xsd files.

然后我将它与 XmlReader 一起使用来读取 xsd.重要的部分是我必须放置一个 basePath 以便 XmlXsdResolve 可以找到其他 xsd 文件.

Then I used it with an XmlReader to read the xsd. The important part is that I had to put a basePath so that the XmlXsdResolve can find other xsd files.

using (XmlReader xsd = XmlReader.Create(new FileStream(xsdPath, FileMode.Open, FileAccess.Read), settings, basePath))
{
    settings.Schemas.Add(null, xsd);
}

settings.Schemas.Compile();

这是用于查找包含和导入的 xsd 文件的 XmlXsdResolver:

This is the XmlXsdResolver to find included and imported xsd files:

protected class XmlXsdResolver : XmlUrlResolver
{
    public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
    {
        return base.GetEntity(absoluteUri, role, ofObjectToReturn);
    }
}

这篇关于针对在 c# 中包含和导入的 xsd 验证 xml的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆