2009-07-01 4 views
8

EDIT私は2つのプロジェクトとVisual Studioのソリューションを持っている/EDIT参照されたスキーマファイルが異なるプロジェクト/アセンブリにある場合、VS内のXSD schemaLocation属性を指定する方法はありますか?

以下の私の解決策を参照してください。

  • プロジェクト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を編集する場合:...これに

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

を要素を含む...エラーが表示されなくなります。しかし、ソリューションのフォルダ階層内でのみ動作するスキーマへの相対パスを提供していることに注意してください。エディタでスキーマを表示しているときには素晴らしいですが、プロジェクトをコンパイルするときはあまり役に立ちません。コンパイル後に "bin"フォルダを見ると、フォルダ階層は全く異なります(2つのxsdファイルは実際には同じフォルダにあります)。

Visual Studioの「既存アイテムをリンクとして追加」機能を使用して、メインのスキーマファイルと同じフォルダにあるReferencedSchema.xsdファイルへのショートカットを作成しようとしましたが、機能しませんでした。 XSDバリデーターは明らかにリンクが実際のファイルであると見せかけることはできません。

私の問題は、両方の状況(ソリューションエクスプローラ内と実行時の間)で有効なschemaLocationを提供できるURIが存在しないようです。誰にも何か提案はありますか?

ありがとうございます!

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; 
    } 

すべては今、私は私のXMLを見てるかどうか動作しているため、私はこのソリューションに行きましたVisual StudioのXSDファイル、またはアプリケーションの実行/デバッグ

+0

間違った場所を指す場所でプロジェクトをコンパイルするとどうなりますか?このスキーマからコードを生成していますか? –

+0

こんにちは、上記の私の編集を参照してください。ありがとう。 – devuxer

答えて

8

XSDは、パスの場所ではなくURIの場所のみをサポートします。つまり、file:///C:/path/to/VS/Projects/ReferencedProject/Data/ReferencedSchema.xsdは有効ですが、../../ReferencedProject/Data/ReferencedSchema.xsdは無効です。

+0

@afroxav、私のためにそれを明確にしてくれてありがとう。私は問題を回避するためのソリューションを考え出しました(上記の私の編集を参照してください)。 – devuxer

+4

'../../path/to/file.xsd'には本質的に間違ったものはありません。これは相対URIであり、XSD仕様で許可され、.NETによって正しく理解されています。もちろん、その場所が存在し、適切なアクセス権を持っている必要があります。 URIは、含まれているドキュメントのドキュメントURI、または最も近い 'xml:base'属性にあるものであるベースURIに対して解決されます。 – Abel

0

パブリックURLまたは共通のネットワーク共有を使用すると、その場所に両方のファイルが置かれます。

1

免責事項:XMLスキーマについてよくわかりません。とにかく、私はあなたと同じ問題に遭遇しました。

xs:includeではなくxs:importを使用すると、VSデザイナーで私の問題が解決されたようです。

まずスキーマ:

<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> 

Visual StudioでXMLスキーマを編集するときは、メニュー項目のXML使用して、アクティブであるスキーマの見ることができます - > [スキーマを。

+1

これは特定の問題を解決する可能性がありますが、スキーマのインポートまたはスキーマのセマンティクスは異なります。インポートでは、インポートの優先順位が有効になり、includeを使用すると、宣言がコピー&ペーストされたかのように動作します。 – Abel

関連する問題