【问题标题】:XmlReaderSettings.Schemas.Add() : The URI prefix is not recognizedXmlReaderSettings.Schemas.Add() :无法识别 URI 前缀
【发布时间】:2020-03-23 02:13:03
【问题描述】:

我在 .Net 4.5 中升级了我的旧应用程序。有一些过时的方法警告我很想解决它们。过时的方法之一是 XmlValidatingReader。 上网查了一下,发现XmlReaderSettings是XmlValidatingReader的潜在替代品。

// ==old code==
Hashtable _SchemasCache = new Hashtable();
XmlReader xmlReader = new XmlTextReader(xmlStream);
XmlValidatingReader validatingReader = new XmlValidatingReader(xmlReader);
validatingReader.Schemas.Add(root.Namespace, schemaLocation); // both parametres are string. No error
_SchemasCache.Add(schemaLocation, validatingReader.Schemas);

// ==new code==
var schemaLocation = "res://somepath/Messages.xsd";
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(root.Namespace, schemaLocation); // this line gives error
_SchemasCache.Add(schemaLocation, settings.Schemas);

旧代码没有给出任何错误,但新代码给出了The URI prefix is not recognized. 的错误我找不到settings.Schemas.Add() 的这种行为的原因,因为它与XmlValidatingReader 一起工作正常。有人可以帮忙吗?

编辑:这里 schemaLocation 的值是“res://somepath/Messages.xsd”。因为 schemaLocation 没有 Http:https:// 或没有 local resource,这就是发生错误的原因。如何使用 XmlReaderSettings

添加具有这些值的架构

编辑 2:由于此 XSD 是嵌入式资源,因此我在网上找到了一些用于此场景的代码。我做了以下代码更改。

Assembly asm = Assembly.Load("AssemblyNameWhereXSDis");
Uri uri = new Uri(@"res://p.a.t.h/Autorisatie/Messages.xsd");
string resourceName1 = asm.GetName().Name + uri.AbsolutePath.Replace("/", ".");

using (Stream schemaStream = myAssembly.GetManifestResourceStream(resourceName1))
{
    using (XmlReader schemaReader = XmlReader.Create(schemaStream)) // this line gives error : value(schemaStream) cannot be null
    {
        settings.Schemas.Add(root.Namespace, schemaReader);
    }
}

这里,schemaStream 的值为空。而resourceName1 的值为assemblyname.folder.Message.xsd

我在 Visual Studio 中将 Message.xsd 设置为 Embedded Resource,但仍然无法正常工作。

【问题讨论】:

  • 您需要在 xml 中定义命名空间的属性,例如:xmlns:abc="myURL";
  • 我怀疑您需要使用模式解析器。另外,微软论坛上的这个问题听起来和你的很相似:social.msdn.microsoft.com/Forums/en-US/…

标签: c# asp.net xsd xmlreader obsolete


【解决方案1】:

问题来源

正如您自己想象的那样 - URI 必须指向某个地方的真实文件 - URL (HTTP/HTTPS) 或本地文件 ("C:\...")。

因此,如果您更喜欢使用嵌入式资源,则需要使用完全指定的路径,格式如下: "Namespace.FolderName.Filename.Extension"

示例

using System;
using System.Linq;
using System.Reflection;
using System.Xml;

// ...

// get full resourceName from current assembly using Linq
var messagesResourceFullName = Assembly.GetExecutingAssembly()
                              .GetManifestResourceNames()
                              .Where(n => n.EndsWith("Messages.xsd"));

using (var schemaStream = asm.GetManifestResourceStream(messagesResourceFullName))
{
    if (schemaStream == null) throw new FileNotFoundException();

    using (var schemaReader = XmlReader.Create(schemaStream))
    {
        settings.Schemas.Add(root.Namespace, schemaReader);
    }
}

source

【讨论】:

  • 嗨。感谢您的回答。 1. 在这种情况下如何使用“Where”?它给出了一个错误,无法使用 Where for System。大批。 2. GetManifestResourceStream() 只接受参数字符串或Type和字符串的组合。
  • 1.添加using System.Linq。 2. 单个字符串重载,这是我在示例中使用的。
【解决方案2】:

在您的代码中添加这一行: 使用 System.Linq;

【讨论】:

    猜你喜欢
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-26
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多