gpt4 book ai didi

c# - 当我的所有 .XSD 都存储为资源时,如何解析 .XSD 的 schemaLocation 属性?

转载 作者:数据小太阳 更新时间:2023-10-29 01:46:50 26 4
gpt4 key购买 nike

我正在从事一个项目,我需要根据嵌套的 XSD 生成 XML 文件。例如ORDER 引用了 PERSON,PERSON 引用了 ADDRESS,等等。

我正在创建一个“XmlReaderSettings”实例来验证 XSD,并在生成 XML 后对其进行验证。

我已将 XSD 作为资源添加到我的程序集中。然后我为每个资源创建一个 XmlSchema 实例,从最低到最高,并将其添加到 XmlReaderSettings.Schemas 集合。

但是,尝试添加引用另一个架构的架构失败。我收到 XmlSchemaException:“对于元素声明,必须存在名称或 ref 属性。”

我在下面包含了示例 XSD 和源代码:

ADDRESS.xsd - 由 PERSON.xsd 引用

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ADDRESS.xsd" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ADDRESS" >
<xs:complexType>
<xs:sequence>
<xs:element name="ADDRESS1" type="xs:string"/>
<xs:element name="ADDRESS2" type="xs:string"/>
<xs:element name="CITY" type="xs:string"/>
<xs:element name="STATE" type="xs:string"/>
<xs:element name="ZIP" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

PERSON.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="PERSON.xsd" attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="ADDRESS.xsd"/>
<xs:element name="PERSON" >
<xs:complexType>
<xs:sequence>
<xs:element name="L_NAME" type="xs:string"/>
<xs:element name="F_NAME" type="xs:string"/>
<xs:element name="Addresses">
<xs:complexType>
<xs:sequence>
<xs:element ref="ADDRESS" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

示例代码 - 加载和验证 XSD

using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using SchemaTest.Properties;

namespace SchemaTest
{
class Program
{
static void Main(string[] args)
{
// create validation settings instance
var xmlReaderSettings = new XmlReaderSettings
{
ValidationType = ValidationType.Schema,
ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema |
XmlSchemaValidationFlags.ProcessSchemaLocation |
XmlSchemaValidationFlags.ReportValidationWarnings
};

xmlReaderSettings.ValidationEventHandler += SchemaValidationEventHandler;

// added XmlResourceResolver, per the accepted answer below
xMLReaderSettings.Schemas.XmlResolver = new XmlResourceResolver();

// load schemas into validation settings instance
LoadSchema(xmlReaderSettings, Resources.PERSON);

// validate schemas
xmlReaderSettings.Schemas.Compile();

Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}

private static void LoadSchema(XmlReaderSettings xmlReaderSettings, string schemaString)
{
using (var schemaStream = new MemoryStream(Encoding.Default.GetBytes(schemaString)))
{
var schema = XmlSchema.Read(schemaStream, null);

try
{
xmlReaderSettings.Schemas.Add(schema);
}
catch (Exception ex)
{
Console.WriteLine("EXCEPTION: {0}", ex.Message);
}
}
}

private static void SchemaValidationEventHandler(object sender, ValidationEventArgs e)
{
Console.WriteLine("{0}: {1}", e.Severity, e.Message);
}
}
}

我不确定这是否与 ValidationFlags 有任何关系,但我尝试删除 XmlSchemaValidationFlags.ProcessSchemaLocation 并且仍然收到相同的错误。我还尝试将 SchemaValidationEventHandler 传递给 XmlSchema.Read 方法(而不是示例代码中的 null),并且模式似乎创建正常,但它仍然会引发异常当尝试将其添加到 XmlReaderSettings.Schemas 集合时。

编辑 - 2011.11.03

我根据接受的答案中的 XmlResolver 类示例,通过创建自己的名为 XmlResourceResolverXmlUrlResolver 后代解决了这个问题(双关语)下面。

最佳答案

要消除错误,请在 PERSON.xsd 文件中将 type="Addresses"更改为 name="Addresses"。

最好使用下面的代码来编译模式。重要的是确保您建立一个基本 uri(因为您正在从流中读取),改为使用 XmlSchemaSet 和自定义解析器(将文件作为嵌入式资源读取)。

using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Schema;

namespace ConsoleApplication3
{
class Program
{
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);
}
}

static void Main(string[] args)
{
using (XmlReader reader = XmlReader.Create(new StringReader(Resource.PERSON), new XmlReaderSettings(), XmlResolver.BaseUri))
{
XmlSchemaSet xset = RetrieveSchemaSet(reader);
Console.WriteLine(xset.IsCompiled);
}
}

private static XmlSchemaSet RetrieveSchemaSet(XmlReader reader)
{
XmlSchemaSet xset = new XmlSchemaSet() { XmlResolver = new XmlResolver() };
xset.Add(XmlSchema.Read(reader, null));
xset.Compile();
return xset;
}
}
}

关于c# - 当我的所有 .XSD 都存储为资源时,如何解析 .XSD 的 schemaLocation 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7982275/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com