2008-12-19 4 views
31

Wie würde ich definieren ein Element, das entweder Klartext oder enthalten Elemente enthalten? Sagen, dass ich für diese beiden Fälle irgendwie erlauben wollte:XML-Schema: Element, das Elemente oder Text enthalten kann?

<xs:element name="field"> 
    <xs:complexType> 
     <xs:sequence> 
      <xs:element ref="subfield" minOccurs="0" maxOccurs="unbounded" /> 
     </xs:sequence> 
     <xs:attribute name="name" type="xs:string" /> 
    </xs:complexType> 
</xs:element> 

<xs:element name="field" type="xs:string" /> 

... so dass diese beiden Elemente wäre gültig:

<field name="test_field_0"> 
    <subfield>Some text.</subfield> 
</field> 

<field name="test_field_1">Some more text.</field> 
+0

können Sie nicht xs verwenden: Wahl? –

Antwort

21

Ich habe einige Forschung auf diesem eine Weile her, und das einzige, ich Lösung gefunden war das gemischte Attribut verwendet:

<xs:element name="field"> 
    <xs:complexType mixed="true"> 
     <xs:sequence> 
       <xs:element ref="subfield" minOccurs="0" maxOccurs="unbounded" /> 
     </xs:sequence> 
     <xs:attribute name="name" type="xs:string" /> 
    </xs:complexType> 
</xs:element> 

Diese leider erlaubt auch

<field name="test_field_0"> 
    Some text I'm sure you don't want. 
    <subfield>Some text.</subfield> 
    More text you don't want. 
</field> 

Hoffentlich wird jemand eine bessere Antwort geben.

+0

Wie wäre es mit 'xs: choice'? – Paciv

+0

Wechseln Sie zu XSD 1.1 und verwenden Sie die bedingte Typzuweisung. Aber Sie brauchen eine XSD 1.1 Implementierung wie Saxon EE denen haben, ist nicht frei :) Ich bin nicht bekannt, dass freie XSD 1.1 Implementierung – lkuty

12

Eine weitere Option ist für Sie Vererbung zu verwenden. Ihre resultierenden XML nicht so schön ist, aber Sie bekommen genau die Inhalte, die Sie wollen:

<xsd:element name="field" type="field" abstract="true" /> 
<xsd:element name="subfield" type="xsd:string" /> 

<xsd:complexType name="field" abstract="true" /> 

<xsd:complexType name="subfield"> 
    <xsd:complexContent> 
    <xsd:extension base="field"> 
     <xsd:sequence> 
     <xsd:element ref="subfield" minOccurs="0" maxOccurs="unbounded" /> 
     </xsd:sequence> 
     <xsd:attribute name="name" type="xsd:string" /> 
    </xsd:extension> 
    </xsd:complexContent> 
</xsd:complexType> 

<xsd:complexType name="no-subfield"> 
    <xsd:complexContent mixed="true"> 
    <xsd:extension base="field"> 
     <xsd:attribute name="name" type="xsd:string" /> 
    </xsd:extension> 
    </xsd:complexContent> 
</xsd:complexType> 

dann Ihre resultierenden XML würde folgende Komponenten enthalten (vorausgesetzt, Sie haben xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" irgendwo erklärt)

<field xsi:type="subfield"> 
    <subfield>your stuff here</subfield> 
</field> 

oder

<field xsi:type="no-subfield">your other stuff</field> 

Am wichtigsten ist, nicht zulässt, es

<field xsi:type="subfield"> 
    Text you don't want 
    <subfield>your stuff here</subfield> 
    More text you don't want 
</field> 
+0

Wenn Sie xsi vermeiden wollen: Art können Sie auch subsitutionGroups mit verschiedenen Elementnamen definieren, so dass Sie setzte in x und foo aber nach wie vor aus dem gleichen Feld Tag vererben. –

Verwandte Themen