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" />
...错误消失了。但是,请注意,我提供了一个仅适用于模式的相对路径within我的解决方案的文件夹层次结构。当我在编辑器中查看架构时,这很好,但当我编译项目时,效果就不那么好了。如果我在编译后查看“bin”文件夹,文件夹层次结构完全不同(两个 xsd 文件实际上最终位于同一文件夹中)。
我尝试使用 Visual Studio 的“将现有项目添加为链接”功能来解决此问题,将 ReferencedSchema.xsd 文件的快捷方式放在与我的主架构文件相同的文件夹中,但这不起作用。 XSD 验证器显然无法假装链接是实际文件。
所以,我的问题是,我似乎没有可以为 schemaLocation 提供的任何 uri 在这两种情况下都有效(在解决方案资源管理器内和运行时期间)。有没有人有什么建议?
Thanks!
EDIT
我决定这样做:
<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 文件还是运行/调试我的应用程序,一切都可以正常工作。