C#针对多个模式xsd验证xml

时间:2014-05-23 17:09:21

标签: c# xml validation xsd schema

我正在寻找一种方法来在内存或运行时针对多个xsd架构验证我的xml文件,而不会触及磁盘文件系统。

我们说我有一个像这样的xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<addresses xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation='test.xsd'>
</addresses>

然后有一个架构:

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

有没有办法在内存中使用多个xsd验证xml?我在考虑使用:

           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);
                }
            }

我收到错误然后我正在尝试编译schemaset,因为listOfSchemasReferenced可能有很多未分隔的xsd放在同一个文件夹中。 当我浏览网页时,我发现XmlResolver可能很有用,但我不确定如何在放置在.zip和内存中的文件上下文中验证多个xsd。 如果你有任何想法如何解决这个问题,或者你有一些我可以阅读的例子会很棒。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

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