针对在 c# 中包含和导入的 xsd 验证 xml
Validating xml against an xsd that has include and import in c#
我想缓存 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());
}
}
}
注意:dtdPath
、xsdPath
有效,输入xml有效,xsd个文件有效
错误是:
The'http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader:StandardBusinessDocument' element is not declared.
我使用以下选项创建了一个 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();
这是 XmlXsdResolver
以查找包含和导入的 xsd 文件:
protected class XmlXsdResolver : XmlUrlResolver
{
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
return base.GetEntity(absoluteUri, role, ofObjectToReturn);
}
}
我想缓存 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());
}
}
}
注意:dtdPath
、xsdPath
有效,输入xml有效,xsd个文件有效
错误是:
The'http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader:StandardBusinessDocument' element is not declared.
我使用以下选项创建了一个 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();
这是 XmlXsdResolver
以查找包含和导入的 xsd 文件:
protected class XmlXsdResolver : XmlUrlResolver
{
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
return base.GetEntity(absoluteUri, role, ofObjectToReturn);
}
}