针对多个模式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。如果你有任何解决这个问题的想法或者你有一些我可以读的例子,那就太好了。

针对多个模式xsd验证xml

我最终使用下面的方法编写了一个自定义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);
        }
    }