xml - 当引用的架构文件位于不同的项目/程序集中时,如何在 VS 中指定 XSD schemaLocation 属性?

标签 xml visual-studio xsd

EDIT 请参阅下面的解决方案/EDIT

我有一个包含两个项目的 Visual Studio 解决方案。

  • 项目 1(称之为 ReferencedProject)包含一个 XML 架构文件 (ReferencedSchema.xsd)。
  • 项目 2(称之为 MainProject)包含 ReferencedProject 作为引用。 MainProject 还有一个架构文件 (MainSchema.xsd)。

MainSchema.xsd 包含以下代码:

<?xml version="1.0"?>
<xs:schema
  xmlns="main"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:tns="main"
  targetNamespace="main"
  elementFormDefault="qualified">
  <xs:include schemaLocation="ReferencedSchema.xsd" />
  ...
</xs:schema>

因为 ReferencedSchema.xsd 不在同一个文件夹中(甚至不在同一个项目中),我收到一条错误消息“无法解析 ReferencedSchema.xsd”。有道理。

如果我将 xs:include 元素编辑为...

<xs:include schemaLocation="../../ReferencedProject/Data/ReferencedSchema.xsd" />

...错误消失了。但是,请注意,我提供了一个架构的相对路径,该路径仅在我的解决方案的文件夹层次结构中 有效。当我在编辑器中查看模式时这很好,但当我编译我的项目时就不是那么好了。如果我在编译后查看我的“bin”文件夹,文件夹层次结构是完全不同的(两个 xsd 文件实际上最终位于同一个文件夹中)。

我尝试使用 Visual Studio 的“将现有项目添加为链接”功能来解决这个问题,将 ReferencedSchema.xsd 文件的快捷方式放在与我的主架构文件相同的文件夹中,但这没有用。 XSD 验证器显然无法假装链接是实际文件。

所以,我的问题是似乎没有任何 uri 我可以为 schemaLocation 提供在两种情况下(在解决方案资源管理器中和运行时)都有效的 uri。有人有什么建议吗?

谢谢!

编辑

我决定这样做:

<xs:include schemaLocation="../../ReferencedProject/Data/ReferencedSchema.xsd" />

只要我在 Visual Studio 中查看内容,这是正确的,但在运行我的代码时不正确。

为了使其在运行时也能正常工作,我动态地将 schemaLocation 替换为正确的相对引用,如下所示:

public class UriReplacingXmlValidator
{
    public virtual XDocument Validate(
        string dataFolderName,
        string baseDataFolderName,
        string xmlFileName,
        string schemaFileName,
        string baseSchemaFileName)
    {
        string rootFolderPath = Environment.CurrentDirectory + Path.DirectorySeparatorChar;
        string dataFolderPath = rootFolderPath + Path.DirectorySeparatorChar + dataFolderName;
        string baseDataFolderPath = rootFolderPath + Path.DirectorySeparatorChar + baseDataFolderName;
        string xmlPath = dataFolderPath + Path.DirectorySeparatorChar + xmlFileName;
        string schemaPath = dataFolderName + Path.DirectorySeparatorChar + schemaFileName;
        string baseSchemaPath = baseDataFolderName + Path.DirectorySeparatorChar + baseSchemaFileName;
        XDocument xmlDocument = XDocument.Load(xmlPath);
        XDocument schemaDocument = XDocument.Load(schemaPath);
        ResetBaseSchemaLocation(schemaDocument, baseSchemaPath);
        XmlValidator validator = new XmlValidator();
        bool isValid = validator.Validate(xmlDocument, schemaDocument);
        if (isValid)
            return xmlDocument;
        else
            return null;
    }

    protected virtual void ResetBaseSchemaLocation(XDocument schemaDocument, string baseSchemaPath)
    {
        XNamespace ns = "http://www.w3.org/2001/XMLSchema";
        XAttribute attribute = schemaDocument.Element(ns + "schema").Element(ns + "redefine").Attribute("schemaLocation");
        attribute.Value = baseSchemaPath;
    }

我选择了这个解决方案,因为无论我是在 Visual Studio 中查看我的 XML 和 XSD 文件,还是运行/调试我的应用程序,现在一切正常。

最佳答案

XSD 只支持 URI 定位,不支持路径定位。这意味着 file:///C:/path/to/VS/Projects/ReferencedProject/Data/ReferencedSchema.xsd 是有效的,但不是 ../../ReferencedProject/Data/ReferencedSchema.xsd.

关于xml - 当引用的架构文件位于不同的项目/程序集中时,如何在 VS 中指定 XSD schemaLocation 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1071849/

相关文章:

java - 针对 xsd 的 Xml 验证接受错误的 xml 为有效

c# - 服务引用未加载 : Schema with target namespace could not be found

C# 应用程序不会在 XML 文档中显示最后一个属性值

visual-studio - 无法使用 DacFX 部署到 Azure 故障转移组内的 Azure SQL 数据库

c# - 查看变量时 Visual Studio 调试器崩溃

xml - 在 XSD 元素中声明命名空间属性

ruby - 从多个 XML 文件解析数据并输出到 csv 文件

php - 扩展布局 .xml 文件在与父主题不同的 <vendor> 子主题中不起作用 : Magento 2. 0.4

c# - LinqToXml 还是 Xml?

c# - Visual C# (Visual Studio) 和 Mono C# GUI 之间的区别