针对在c#中包含和导入的xsd验证xml

时间:2018-02-19 16:21:06

标签: c# xml xsd .net-core xml-validation

我想缓存xsd然后对其执行验证,而不是每次为任何xml加载xsd以提高性能。但是,我无法做到这一点。我的猜测是编译没有添加xsd文件的include和import元素,这就是我在下面得到错误的原因。

以下是步骤:

首先我将xsd文件添加到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,如下所示:

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文件有效

错误是: The'http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader:StandardBusinessDocument' element is not declared.

1 个答案:

答案 0 :(得分:2)

我使用以下选项创建了XmlReaderSettings

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文件。

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

settings.Schemas.Compile();

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

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