我正在寻找一种方法来在内存或运行时针对多个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。 如果你有任何想法如何解决这个问题,或者你有一些我可以阅读的例子会很棒。任何帮助表示赞赏。
答案 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);
}
}