2011-06-27 12 views
4

多くのタイプがいくつかの「マジックナンバー」を共有しているXMLスキーマを作成しようとしています。XMLスキーマでエンティティ '定数'を使用する

これらのマジックナンバーが変更された場合に、いくつかの場所でスキーマを変更するのではなく、何らかの定数定義に変更したいと思います。

私は、スキーマにDTDを追加し、ここにいくつかのエンティティを宣言して遊んでいます。しかし、私は決してDTDの専門家ではなく、スキーマを使用するC#アプリケーションで動作するようですが、msxml 4.0で同じスキーマを使用するネイティブWin32アプリケーションもあります。

この方法でスキーマ定義を拡張した経験がある人はいますか(それはできますか)、より良い方法がありますか?

(EDIT:例)

例XML:スキーマをロードする

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE schema [ 
    <!ENTITY SomeMagicNumber "10">]> 
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" 
      elementFormDefault="qualified" 
      xmlns:mstns="http://tempuri.org/XMLSchema.xsd" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <xs:simpleType name="MySimpleType"> 
    <xs:restriction base="xs:int"> 
     <xs:maxInclusive value="&SomeMagicNumber;" /> 
    </xs:restriction> 
    </xs:simpleType> 

    <xs:complexType name="MyIntegers"> 
    <xs:sequence> 
     <xs:element name="value" type="xs:int" maxOccurs="&SomeMagicNumber;" /> 
    </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="MyFloats"> 
    <xs:sequence> 
     <xs:element name="value" type="xs:float" maxOccurs="&SomeMagicNumber;" /> 
    </xs:sequence> 
    </xs:complexType> 

</xs:schema> 

例デルファイのWin32コード:

var 
    XmlSchemas: IXMLDOMSchemaCollection; 
    XmlSchema: IXMLDOMDocument2; 
    XmlDocument: IXMLDOMDocument2; 
begin 
    XmlSchemas := CoXMLSchemaCache40.Create; 

    XmlSchema := CoDOMDocument40.Create; 
    XmlSchema.load((*INSERT SCHEMA PATH HERE*)); 
    Assert(XmlSchema.parseError.errorCode = 0, XmlSchema.parseError.reason); 
    XmlSchemas.add((*INSERT SCHEMA TARGET NAMESPACE HERE*), XmlSchema); 

    XmlDocument := CoDOMDocument40.Create; 
    XmlDocument.schemas := XmlSchemas; 
    XmlDocument.validateOnParse := True; 
end; 

コードスキーマをロードしようとした後にアサートします。理由: '一番上の要素の名前は、DOCTYPE宣言の名前と一致する必要があります。'

答えて

2

はい、エンティティを使用して、XMLスキーマファイルの定数を定義できます。

スキーマを読み込もうとした後にコードがアサートされます。理由: ' の名前の一番上の要素は、DOCTYPE宣言の の名前と一致する必要があります。'

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE schema [ 
    <!ENTITY SomeMagicNumber "10"> 
]> 
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" 
      elementFormDefault="qualified" 
      xmlns:mstns="http://tempuri.org/XMLSchema.xsd" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    ...(clipped away) 

</xs:schema> 

あなたの問題は、DTDには、名前空間を認識していないことに起因します。このため、パーサにはルート要素<schema>を定義するDTDがあり、ドキュメントにはルート要素<xs:schema>があります。代わりに<!DOCTYPE xs:schema [を使用してみてください。この接頭辞 "ハードコーディング"は誤っているように見えるかもしれませんが、DTDでは名前空間接頭辞マッピングを持つ簡単な一般的な方法はありません。

複数のスキーマで同じ「マジックナンバー」を使用する場合は、エンティティを別々のDTDに定義し、組み込みDTDのパラメータエンティティを使用してそのエンティティを参照することもできます。

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xs:schema [ 
    <!ENTITY % magicNumbers SYSTEM "url/to/your/entity/dtd-document"> 
    %magicNumbers; 
]> 
<xs:schema ... > 
+0

これはうまくいくようです。 残念ながら、これはVisual Studio XMLエディタでインテリセンスを微調整するようにも見えます。いくつか勝ち、いくぶん失います。 –

0

共通のxsdを作成し、それを他のスキーマからインポートすることができます。 Importing Typesを参照してください。

レポートスキーマのreport.xsdは、別のスキーマおよび別のターゲット名前空間に定義されている単純型xipo:SKUを使用します。エンティティが許可され、サポートされているので、

<import namespace="http://www.example.com/IPO"/> 
+0

一般的なスキーマのインポートは便利ですが、現在の問題ではあまり役に立ちません。私は共有型ではなく、自分のスキーマ内のエンティティ(定数)を宣言したいと思います。 Mads Hansenの投稿は、これが可能であることを暗示しているようですが、どういうわけか、私はそれを間違ってやっています。 –

2

W3CスキーマXSDは、XML文書です。スキーマファイルを読み込んで処理すると、エンティティが展開されてXML情報セットが生成されます。ところで

http://www.xml.com/pub/a/2002/02/27/q-and-a.html

、XSDはもちろん、XML 文書そのものなので、スキーマ自体の中 エンティティを使用してからあなたを防ぐ は何もありません。 XMLスキーマを使用して エンティティを他のドキュメントで宣言することはできません。

エンティティは、XMLインスタンスファイルのコピー/貼り付けやメンテナンスを避けるための便利な方法です。

スキーマを解析するときにネイティブWin32アプリケーションで "爆発"すると、MSXML 4.0またはネイティブWin32アプリケーションのバグのように聞こえます。

+0

私は何をしようとしているのかの短い例を投稿しました。 –

+0

上記のスキーマはC#で読み込まれます(XmlReaderでDTDを許可している場合)。 DTDをルート要素に一致させるように見えないので、示されたDelphiの例は失敗します...私は決してDTDの専門家ではありません - ここでDTDを宣言している方法では、 XMLSchemaの_real_ DTDと関係がありますか?代わりにXMLSchema.dtdを_extend_できますか? –

関連する問題