xml 当引用的架构文件位于不同的项目/程序集中时,如何在 VS 中指定 XSD schemaLocation 属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1071849/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to specify an XSD schemaLocation attribute in VS when the referenced schema file is in a different project/assembly?
提问by devuxer
EDITSee my solution below /EDIT
编辑在下面查看我的解决方案/编辑
I have a Visual Studio solution with two projects.
我有一个包含两个项目的 Visual Studio 解决方案。
- Project 1 (call it ReferencedProject) contains an XML schema file (ReferencedSchema.xsd).
- Project 2 (call it MainProject) contains ReferencedProject as a reference. MainProject also has a schema file (MainSchema.xsd).
- 项目 1(称为 ReferencedProject)包含一个 XML 模式文件 (ReferencedSchema.xsd)。
- 项目 2(称为 MainProject)包含 ReferencedProject 作为参考。MainProject 还有一个架构文件 (MainSchema.xsd)。
MainSchema.xsd contains the following code:
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>
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.
因为 ReferencedSchema.xsd 不在同一个文件夹中(甚至不在同一个项目中),我收到一条错误消息,提示“ReferencedSchema.xsd 无法解析”。说得通。
If I edit the xs:include element to this...
如果我将 xs:include 元素编辑为此...
<xs:include schemaLocation="../../ReferencedProject/Data/ReferencedSchema.xsd" />
...the error goes away. However, notice that I've provided a relative path to the schema that will only work withinmy 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).
...错误消失了。但是,请注意,我提供了架构的相对路径,该路径仅适用于我的解决方案的文件夹层次结构。当我在编辑器中查看架构时这很好,但在我编译我的项目时就不那么好了。如果我在编译后查看我的“bin”文件夹,文件夹层次结构是完全不同的(两个 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.
我尝试使用 Visual Studio 的“将现有项目添加为链接”功能来解决这个问题,将 ReferencedSchema.xsd 文件的快捷方式放在与我的主架构文件相同的文件夹中,但这不起作用。XSD 验证器显然无法假装链接是实际文件。
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?
所以,我的问题是,似乎没有任何我可以为 schemaLocation 提供的 uri 在两种情况下都有效(在解决方案资源管理器中和运行时)。有没有人有什么建议?
Thanks!
谢谢!
EDIT
编辑
I decided to go with this:
我决定这样做:
<xs:include schemaLocation="../../ReferencedProject/Data/ReferencedSchema.xsd" />
This is correct as long as I'm viewing things within Visual Studio, incorrect when running my code.
只要我在 Visual Studio 中查看内容,这就是正确的,但在运行我的代码时不正确。
To make it work at runtime as well, I dynamically replace the schemaLocation with the correct relative reference as follows:
为了使其在运行时也能正常工作,我用正确的相对引用动态替换了 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;
}
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.
我选择了这个解决方案,因为现在无论我是在 Visual Studio 中查看我的 XML 和 XSD 文件还是运行/调试我的应用程序,一切都可以正常工作。
回答by T0xicCode
XSD only supports URI locations, not path location. This means that file:///C:/path/to/VS/Projects/ReferencedProject/Data/ReferencedSchema.xsdis valid, but not ../../ReferencedProject/Data/ReferencedSchema.xsd.
XSD 仅支持 URI 位置,不支持路径位置。这意味着这file:///C:/path/to/VS/Projects/ReferencedProject/Data/ReferencedSchema.xsd是有效的,但不是../../ReferencedProject/Data/ReferencedSchema.xsd。
回答by Menno Deij - van Rijswijk
Disclaimer: I don't know a lot about XML schema. Anyway, I ran into the same problem as you.
免责声明:我对 XML 模式了解不多。无论如何,我遇到了和你一样的问题。
Using xs:import rather than xs:include seemed to solve my problem in VS designer.
使用 xs:import 而不是 xs:include 似乎解决了我在 VS 设计器中的问题。
First schema:
第一个架构:
<xs:schema id="schema1"
targetNamespace="http://tempuri.org/schema1.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/schema1.xsd"
xmlns:mstns="http://tempuri.org/schema1.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:element name="MyType" nillable="true"/>
<xs:complexType name="MyType">
<xs:all>
<xs:element name="Value1" type="xs:double"/>
<xs:element name="Value2" type="xs:double"/>
</xs:all>
</xs:complexType>
</xs:schema>
Second schema:
第二个架构:
<xs:schema id="schema2"
targetNamespace="http://tempuri.org/schema2.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/schema2.xsd"
xmlns:mstns="http://tempuri.org/schema2.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:schema1="http://tempuri.org/schema1.xsd"
>
<xs:import namespace="http://tempuri.org/schema1.xsd"/>
<xs:element name="MySecondType" nillable="true"/>
<xs:complexType name=MySecondType>
<xs:element name="Value" type="schema1:MyType/>
</xs:complexType>
</xs:schema>
When editing XML schema in Visual Studio, you can see which schema's are active using menu item XML --> Schemas.
在 Visual Studio 中编辑 XML 架构时,您可以使用菜单项 XML --> 架构查看哪些架构处于活动状态。
回答by Eric Schneider
Use a public URL or a common network share put both files at that location.
使用公共 URL 或公共网络共享将两个文件放在该位置。

