Как указать атрибут xsd schemaLocation в VS, когда ссылочный файл схемы находится в другом проекте / сборке?
редактировать см. мое решение ниже / 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, который будет действителен в обеих ситуациях (в обозревателе решений и во время выполнения). У кого-нибудь есть предложения?
спасибо!
редактировать
Я решил пойти с этим:
<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;
}
Я пошел с этим решением, потому что теперь все работает, просматриваю ли я XML и XSD-файлы в Visual Studio или запускаю/отлаживаю свое приложение.
3 ответов
XSD поддерживает только местоположения URI, а не местоположение пути. Это значит, что file:///C:/path/to/VS/Projects/ReferencedProject/Data/ReferencedSchema.xsd
действительно, но не ../../ReferencedProject/Data/ReferencedSchema.xsd
.
отказ от ответственности: я не знаю много о схеме XML. В любом случае, я столкнулся с той же проблемой, что и ты.
использование xs: import, а не xs:include, казалось, решило мою проблему в VS designer.
первая схема:
<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>
вторая схема:
<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>
при редактировании схемы XML в Visual Studio можно увидеть, какие схемы активны, используя пункт меню XML --> схемы.