当引用的模式文件位于其他项目/程序集中时,如何在VS中指定XSD schemaLocation属性? [英] How to specify an XSD schemaLocation attribute in VS when the referenced schema file is in a different project/assembly?

查看:145
本文介绍了当引用的模式文件位于其他项目/程序集中时,如何在VS中指定XSD schemaLocation属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑,请参见下面的我的解决方案/EDIT

EDIT See my solution below /EDIT

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

I have a Visual Studio solution with two projects.

  • 项目1(称为ReferencedProject)包含一个XML模式文件(ReferencedSchema.xsd).
  • 项目2(称为MainProject)包含ReferencedProject作为参考. MainProject还具有一个架构文件(MainSchema.xsd).

MainSchema.xsd包含以下代码:

MainSchema.xsd contains the following code:

<?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无法解析".有道理.

Because ReferencedSchema.xsd is not in the same folder (it's not even in the same project), I get an error saying "ReferencedSchema.xsd could not be resolved." Makes sense.

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

If I edit the xs:include element to this...

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

...错误消失了.但是,请注意,我已经提供了一个相对路径,该路径仅在解决方案的文件夹层次结构内起作用.当我在编辑器中查看模式时,这很棒,但是当我编译项目时,效果就不那么理想了.如果在编译后查看"bin"文件夹,则文件夹层次结构完全不同(两个xsd文件实际上位于同一文件夹中).

...the error goes away. However, notice that I've provided a relative path to the schema that will only work within my solution's folder hierarchy. That's great when I'm viewing the schema in the editor but not so great when I compile my project. If I look in my "bin" folder after compiling, the folder hierarchy is completely different (the two xsd files actually end up in the same folder).

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

I tried to get around this using Visual Studio's "Add Existing Item As Link" feature, putting a shortcut to the ReferencedSchema.xsd file in the same folder as my main schema file, but that didn't work. The XSD validator apparently isn't capable of pretending the link is the actual file.

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

So, my problem is that there doesn't seem to be any uri I can provide for schemaLocation that will be valid in both situations (within the solution explorer and during runtime). Does anyone have any suggestions?

谢谢!

编辑

我决定要这样做:

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

只要我在Visual Studio中查看内容,这是正确的,而在运行我的代码时是错误的.

This is correct as long as I'm viewing things within Visual Studio, incorrect when running my code.

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

To make it work at runtime as well, I dynamically replace the schemaLocation with the correct relative reference as follows:

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文件还是运行/调试应用程序,一切都可以正常工作.

I went with this solution because everything now works whether I'm viewing my XML and XSD files in Visual Studio or running/debugging my app.

推荐答案

XSD仅支持URI位置,不支持路径位置.这表示file:///C:/path/to/VS/Projects/ReferencedProject/Data/ReferencedSchema.xsd有效,但../../ReferencedProject/Data/ReferencedSchema.xsd无效.

XSD only supports URI locations, not path location. This means that file:///C:/path/to/VS/Projects/ReferencedProject/Data/ReferencedSchema.xsd is valid, but not ../../ReferencedProject/Data/ReferencedSchema.xsd.

这篇关于当引用的模式文件位于其他项目/程序集中时,如何在VS中指定XSD schemaLocation属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆