针对多个模式xsd验证xml
本文关键字:xsd 验证 xml 模式 | 更新日期: 2023-09-27 18:04:54
我正在寻找一种方法来验证我的xml文件在内存中或在运行时针对多个xsd模式,而不触及磁盘文件系统。
假设我有一个这样的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<addresses xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation='test.xsd'>
</addresses>
则有一个schema:
<?xml version="1.0" encoding="utf-8"?>
<schema targetNamespace="xxx">
<!-- include and import declarations -->
<include schemaLocation="another.xsd"/>
<import schemaLocation="dev.xsd"/>
<!--
this .xsd does not have any schema components defined.
removed from schema file set.
<include schemaLocation="new.xsd"/>
-->
<include schemaLocation="old.xsd"/>
<include schemaLocation="test4.xsd"/>
<include schemaLocation="test2.xsd"/>
<include schemaLocation="test3.xsd"/>
让我们假设一些简化的图表看起来像这样:
test.xsd
| | |
test1.xsd test2.xsd test3.xsd
| |
test5.xsd test6.xsd
等等…
当我使用任何工具进行模式验证时,我将所有xsd文件放在一个文件夹中,然后我可以很好地验证xml。
我想在不使用文件系统上的目录的情况下达到同样的效果。我正在考虑将所有这些xsd放在zip中,然后在运行时将它们取回并放在XmlSchemaSet中。问题是,我可能有一些与test.xml无关的额外xsd文件。
是否有任何方法来验证xml与多个xsd在内存中?我正在考虑使用:
foreach (String singleSchema in schema.listOfSchemasReferenced)
{
using (StringReader stringReader = new StringReader(singleSchema))
using (XmlTextReader xmlReader = new XmlTextReader(stringReader))
{
var includeSchema = XmlSchema.Read(xmlReader, null);
var include = new XmlSchemaInclude();
include.Schema = includeSchema;
if (mainSchema.TargetNamespace != includeSchema.TargetNamespace)
continue;
mainSchema.Includes.Add(include);
}
}
我得到错误,然后我试图编译schemasset,因为listOfSchemasReferenced可能有很多不相关的xsd放在同一个文件夹中。当我通过web查看时,我已经看到XmlResolver可能很有用,但我不确定如何在.zip和内存中放置的文件的上下文中使用验证多个xsd。如果你有任何解决这个问题的想法或者你有一些我可以读的例子,那就太好了。
我最终使用下面的方法编写了一个自定义xml解析器:
class XmlResolver : XmlUrlResolver
{
internal const string BaseUri = "schema://";
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
if (absoluteUri.Scheme == "schema")
{
switch (absoluteUri.LocalPath)
{
case "/ADDRESS.xsd":
return new MemoryStream(Encoding.UTF8.GetBytes(Resource.ADDRESS));
case "/PERSON.xsd":
return new MemoryStream(Encoding.UTF8.GetBytes(Resource.PERSON));
}
}
return base.GetEntity(absoluteUri, role, ofObjectToReturn);
}
}