Как указать атрибут 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 --> схемы.


используйте общедоступный URL или общий сетевой ресурс, поместите оба файла в это место.