2012-01-13 15 views
45

次のポストは、要素が のルート要素のXMLスキーマであることを示すために、どのように求められます。XMLスキーマ:ルート要素

Is it possible to define a root element in an XML Document using Schema?

私はXMLスキーマにW3Schoolsのチュートリアルに従ってきたが、何かがまだあります定かでない。 例のスキーマ2をhttp://www.w3schools.com/schema/schema_example.asp (便宜上以下に再現)から考えてください。このコードは、<shiporder> がルート要素であることをどのように示していますか?すべての要素 がルート要素として有効であるという例はありませんか?

------------------例--------------------------- -------

<?xml version="1.0" encoding="ISO-8859-1"?> 

<shiporder orderid="889923" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="shiporder.xsd"> 
    <orderperson>John Smith</orderperson> 
    <shipto> 
    <name>Ola Nordmann</name> 
    <address>Langgt 23</address> 
    <city>4000 Stavanger</city> 
    <country>Norway</country> 
    </shipto> 
    <item> 
    <title>Empire Burlesque</title> 
    <note>Special Edition</note> 
    <quantity>1</quantity> 
    <price>10.90</price> 
    </item> 
    <item> 
    <title>Hide your heart</title> 
    <quantity>1</xample saying that all elements are valid as root elements?quantity> 
    <price>9.90</price> 
    </item> 
</shiporder> 

-----------------------スキーマ------------デフ

  1. :------------私の視点から

    <?xml version="1.0" encoding="ISO-8859-1" ?> 
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    
    <!-- definition of simple elements --> 
    <xs:element name="orderperson" type="xs:string"/> 
    <xs:element name="name" type="xs:string"/> 
    <xs:element name="address" type="xs:string"/> 
    <xs:element name="city" type="xs:string"/> 
    <xs:element name="country" type="xs:string"/> 
    <xs:element name="title" type="xs:string"/> 
    <xs:element name="note" type="xs:string"/> 
    <xs:element name="quantity" type="xs:positiveInteger"/> 
    <xs:element name="price" type="xs:decimal"/> 
    
    <!-- definition of attributes --> 
    <xs:attribute name="orderid" type="xs:string"/> 
    
    <!-- definition of complex elements --> 
    <xs:element name="shipto"> 
        <xs:complexType> 
        <xs:sequence> 
         <xs:element ref="name"/> 
         <xs:element ref="address"/> 
         <xs:element ref="city"/> 
         <xs:element ref="country"/> 
        </xs:sequence> 
        </xs:complexType> 
    </xs:element> 
    
    <xs:element name="item"> 
        <xs:complexType> 
        <xs:sequence> 
         <xs:element ref="title"/> 
         <xs:element ref="note" minOccurs="0"/> 
         <xs:element ref="quantity"/> 
         <xs:element ref="price"/> 
        </xs:sequence> 
        </xs:complexType> 
    </xs:element> 
    
    <xs:element name="shiporder"> 
        <xs:complexType> 
        <xs:sequence> 
         <xs:element ref="orderperson"/> 
         <xs:element ref="shipto"/> 
         <xs:element ref="item" maxOccurs="unbounded"/> 
        </xs:sequence> 
        <xs:attribute ref="orderid" use="required"/> 
        </xs:complexType> 
    </xs:element> 
    
    </xs:schema> 
    

    XMLスキーマは2つのことを行う必要がありますINE何を各ノードが

を配置することができる

  • 定義各ノード内に発生し、例では#2で失敗と思われることができます。 提案がありますか?

  • +0

    私はリンクのアドバイスにちょうど従っていました。私は、上記のXMLスキーマで定義された要素のいずれかがドキュメントのルート要素として発生する可能性がありますが、正しいと思いますか?ありがとう。 – johngoche9999

    +0

    質問者が間違ってやっていることと、彼がそれをどのように修正できるかについての深い説明のために、Brian Driscollさん、ありがとうございます。 – fool4jesus

    答えて

    43

    グローバルに定義された要素は、ルート要素として使用できます。また、XMLスキーマには、ルート要素の内容を指定する概念がありません。

    一つだけグローバルに定義された要素があるように、あなたはしかし、よくあなたのXMLスキーマを設計することにより、この問題を回避することができます - そして、これだけの要素はルート要素として有効です。

    この例は、(名前付きタイプ指定を使用を見出し)W3Schoolsで見つけることができ この例では、唯一のグローバルに定義された要素を有しており、従って唯一の可能なルート要素。

    +0

    ありがとう、私は、w3schoolsサイトの例3は実際にはおそらく、すべての単純なタイプと複雑なタイプを定義してから、グローバルに定義された単一のエレメントを持つことによって単一のルートエレメントをdesginateするという問題にアプローチする最良の方法だと思います。 – johngoche9999

    +2

    リンクが無効です。 – Xenos

    +0

    WayBack Machineには、https://web.archive.org/web/20140201170920/http://www.w3schools.com/schema/schema_example.asp –

    14

    はい、あなたは正しいです。 XSDは次のようになります。

    <?xml version="1.0" encoding="ISO-8859-1" ?> 
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    
    <!-- definition of attributes --> 
    <xs:attribute name="orderid" type="xs:string"/> 
    
    <!-- definition of complex elements --> 
    <xs:complexType name="shiptoType"> 
        <xs:sequence> 
        <xs:element name="name" type="xs:string" /> 
        <xs:element name="address" type="xs:string" /> 
        <xs:element name="city" type="xs:string" /> 
        <xs:element name="country" type="xs:string" /> 
        </xs:sequence> 
    </xs:complexType> 
    
    <xs:complexType name="itemType"> 
        <xs:sequence> 
        <xs:element name="title" type="xs:string" /> 
        <xs:element name="note" minOccurs="0" type="xs:string" /> 
        <xs:element name="quantity" type="xs:string" /> 
        <xs:element name="price" type="xs:string" /> 
        </xs:sequence> 
    </xs:complexType> 
    
    <xs:element name="shiporder"> 
        <xs:complexType> 
        <xs:sequence> 
         <xs:element name="orderperson" type="xs:string" /> 
         <xs:element name="shipto" type="shiptoType"/> 
         <xs:element name="item" maxOccurs="unbounded" type="itemType"/> 
        </xs:sequence> 
        <xs:attribute ref="orderid" use="required"/> 
        </xs:complexType> 
    </xs:element> 
    
    </xs:schema> 
    

    あなたが見るように、今だけ1 xs:elementがあり、その1は有効なルート要素とすることができる唯一の一つです:)

    0

    このコードはそれがあることを示しどのようにルート要素?ちょうどすべての要素およびそれらのいずれかがルート要素として選択することができる定義されたスキーマ

    ジョン、 。 Altova XML Spyまたはその類のようなツールからサンプルのXMLを生成しようとすると、要素をルート要素として選択することになります。

    これらの要素のいずれかがルートになる可能性があります。

    1つのグローバルに定義された要素を使用して、あいまいさを防ぐために。

    19

    誰もが同意するわけではありませんが、XMLスキーマでルート要素を指定できないというのは設計によるものです。考えているのは、<invoice>が文書内の唯一のものである場合に有効であれば、それが他のものに含まれている場合にも同様です。コンテンツは再利用可能でなければならず、有効なコンテンツを使用している誰かがより大きなものの一部として使用することを禁止するべきではありません。

    (IDとIDREFが文書にスコープされているという事実はなく、このポリシーに反する。しかし、言語はかなり大規模な委員会によって設計されました。)

    +5

    IDとIDREFは、20年前の異なる組織で全く異なる委員会によって設計されました。 –

    +0

    @Michaelここでは、あるスキーマ内のすべての要素を生成し、そのうちの1つだけがルート要素であり、別のスキーマを作成し、要素を定義するものを含めることが重要である場合は、新しいものはルート要素としてそれらのうちの1つだけを定義し、他のものは制限に適合するように定義します。 – starturtle

    +0

    いいえ、それは間違った推論です。ご質問がある場合は、古い質問にコメントするのではなく、新しい質問を投稿してください。 –

    1

    グローバル要素の多くの欠点は、すべての可能性あり文書のルート要素として使用することができます。利点は、子要素の名前空間が親型の名前空間と一致することを保証する新しい型を定義するときに要素を使用できることです。

    私は、すべての複合型がグローバル要素を持つべきであるというグローバル要素が1つだけあるべきであると考えるから変更しました。

    0

    指定した例に基づいて、唯一のルート要素を見つけることができます。

    グローバル要素のリストを取得し、ノードxs:sequenceの下でcomplexTypeで参照されるネストされた要素をリストとして取得できます。ルート要素はグローバル要素リストにありますが、ネスト要素リストにはありません。

    .NETでXmlSchemaSetクラスを使用してこれを行いました。ここでは、コードスニペットは次のとおりです。

    var localSchema = schemaSet.Schemas().OfType<XmlSchema>().Where(x => !x.SourceUri.StartsWith("http")).ToList(); 
    
    var globalComplexTypes = localSchema 
    .SelectMany(x => x.Elements.Values.OfType<XmlSchemaElement>()) 
    .Where(x => x.ElementSchemaType is XmlSchemaComplexType) 
    .ToList(); 
    
    var nestedTypes = globalComplexTypes.Select(x => x.ElementSchemaType) 
    .OfType<XmlSchemaComplexType>() 
    .Select(x => x.ContentTypeParticle) 
    .OfType<XmlSchemaGroupBase>() 
    .SelectMany(x => x.GetNestedTypes()) 
    .ToList(); 
    
    var rootElement= globalComplexTypes.Single(x => !nestedTypes.Select(y => y.ElementSchemaType.QualifiedName).Contains(x.SchemaTypeName)); 
    

    拡張メソッドのGetNestedTypes:このアプローチを使用するとき

    static IEnumerable<XmlSchemaElement> GetNestedTypes(this XmlSchemaGroupBase xmlSchemaGroupBase) 
    { 
        if (xmlSchemaGroupBase != null) 
        { 
         foreach (var xmlSchemaObject in xmlSchemaGroupBase.Items) 
         { 
          var element = xmlSchemaObject as XmlSchemaElement; 
          if (element != null) 
           yield return element; 
          else 
          { 
           var group = xmlSchemaObject as XmlSchemaGroupBase; 
           if (group != null) 
            foreach (var item in group.GetNestedTypes()) 
             yield return item; 
          } 
         } 
        } 
    } 
    

    しかし、そこには、まだ一般のxsd問題があります。

    <xs:element name="configuration"> 
        <xs:complexType> 
         <xs:choice minOccurs="0" maxOccurs="unbounded"> 
         <xs:any namespace="##any" processContents="lax" /> 
         </xs:choice> 
         <xs:anyAttribute namespace="http://schemas.microsoft.com/XML-Document-Transform" processContents="strict"/> 
        </xs:complexType> 
        </xs:element> 
    

    私はまだスキーマのすべての種類に対処するための完全なソリューションを見つけやりなさい: は例えば、DotNetConfig.xsdに設定ファイルのVisual Studioを使用することを、ルート要素は以下のように定義しています。それを続けます。

    関連する問題