XSD - किसी भी क्रम में किसी भी समय तत्वों को कैसे अनुमति दें?


109

मैं एक XSD बनाने की कोशिश कर रहा हूं, और निम्नलिखित आवश्यकता के साथ परिभाषा लिखने की कोशिश कर रहा हूं:

  • निर्दिष्ट बच्चे तत्व को किसी भी समय (किसी भी संख्या में) दिखाई देने की अनुमति दें
  • बाल तत्वों को किसी भी क्रम में होने दें

मैंने चारों ओर देखा और इस तरह के विभिन्न समाधान पाए :

<xs:element name="foo">
  <xsl:complexType>
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="child1" type="xs:int"/>
      <xs:element name="child2" type="xs:string"/>
    </xs:choice>
  </xs:complexType>
</xs:element>

लेकिन जो मैं एक्स को समझता हूं: विकल्प अभी भी केवल एकल तत्व चयन की अनुमति देता है। इसलिए इस तरह से अनधिकृत रूप से मैक्सओर्स को सेट करने का मतलब केवल यह होना चाहिए कि बाल तत्वों का "कोई भी" कई बार दिखाई दे सकता है। क्या यह सही है?

यदि उपरोक्त समाधान गलत है, तो मैं अपनी आवश्यकता के अनुसार ऊपर बताए गए तरीके को कैसे प्राप्त कर सकता हूं?

संपादित करें : क्या होगा यदि आवश्यकता निम्नानुसार है?

  • एलीमेंट चाइल्ड 1 चाइल्ड 2 किसी भी समय (0 से अनबाउंड) में दिखाई दे सकता है
  • किसी भी क्रम में होने के लिए तत्व
  • तत्व चाइल्ड 3 और चाइल्ड 4 बिल्कुल एक बार दिखाई देने चाहिए।

उदाहरण के लिए, यह xml मान्य है:

<foo>
<child1> value </child1>
<child1> value </child1>
<child3> value </child3>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>

लेकिन यह नहीं है (बच्चा 3 लापता)

<foo>
<child1> value </child1>
<child1> value </child1>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>

जवाबों:


61

आपके प्रश्न में स्कीमा में, child1या child2किसी भी क्रम में, किसी भी समय दिखाई दे सकता है। तो यह लगता है कि आप क्या देख रहे हैं।

संपादित करें: यदि आप उनमें से केवल एक को असीमित संख्या में दिखाना चाहते हैं, तो अनबिके को इसके बजाय तत्वों पर जाना होगा:

संपादित करें: XML में निश्चित प्रकार।

संपादित करें: अधिकतम ओ में अधिकतम पूंजीकृत

<xs:element name="foo">
   <xs:complexType>
     <xs:choice maxOccurs="unbounded">
       <xs:element name="child1" type="xs:int" maxOccurs="unbounded"/>
       <xs:element name="child2" type="xs:string" maxOccurs="unbounded"/>
     </xs:choice>
   </xs:complexType>
</xs:element>

मूल रूप से हाँ, मैं तत्वों child1, child2 के लिए किसी भी क्रम में प्रकट होने के लिए देख रहा हूँ, किसी भी समय की संख्या .. आप यहाँ उपलब्ध कराया जवाब केवल एकल तत्व के लिए काम करता है, है ना? या क्या यह मेरी आवश्यकता को भी हल करता है?
jvtech

आपके प्रश्न में स्कीमा आपकी आवश्यकता को पूरा करती है; मेरे उत्तर में वैकल्पिक स्कीमा एक तत्व के लिए है। आशा है आप यह बात समझ गए होंगे! :)
xcut

@Pavel, @xcut, स्पष्टीकरण के लिए धन्यवाद, संपादित आवश्यकता देखें .. कोई विचार?
20

2
jvtech: आप XML स्कीमा के साथ उस संपादित आवश्यकता को संतुष्ट नहीं कर सकते; इसे प्राप्त करने का एकमात्र तरीका यह होगा कि चाइल्ड 3 और चाइल्ड 4 केवल अंत में दिखाई दे सकते हैं। किस मामले में आपको एक अनुक्रम की आवश्यकता होती है जिसमें एक विकल्प और फिर दो तत्व होते हैं।
कलकत्ता

1
@ Daij-Djan मैंने यह भी पाया कि यह काम नहीं किया। पसंद तत्व पर अधिकतमऑक्सर्स = "अनबाउंड" जोड़ने की कोशिश करें ताकि एक से अधिक बच्चे तत्व की अनुमति हो।
माइक

107

बाद के संपादन में जोड़े गए प्रश्न का वैकल्पिक सूत्रीकरण अभी भी अनुत्तरित है: यह निर्दिष्ट करने के लिए कि किसी तत्व के बच्चों के बीच , क्रम में कोई बाधा के साथ एक नाम child3, एक नाम child4, और किसी भी नाम child1या किसी भी संख्या का होना चाहिए child2। जो बच्चे दिखाई देते हैं।

यह एक सीधा-साधा निश्चित नियमित भाषा है, और आपको जिस कंटेंट मॉडल की आवश्यकता है, वह आइसोमोर्फिक है जो एक रेगुलर एक्सप्रेशन है जो स्ट्रिंग्स के सेट को परिभाषित करता है जिसमें अंक '3' और '4' प्रत्येक में एक बार ठीक होता है, और अंक '1' और '2' में होते हैं। 'किसी भी संख्या में होते हैं। यदि यह स्पष्ट नहीं है कि इसे कैसे लिखना है, तो यह सोचने में मदद मिल सकती है कि आप इस तरह की भाषा को पहचानने के लिए किस प्रकार की परिमित राज्य मशीन का निर्माण करेंगे। इसमें कम से कम चार अलग-अलग राज्य होंगे:

  • एक प्रारंभिक अवस्था जिसमें न तो '3' और न ही '4' देखा गया हो
  • एक मध्यवर्ती राज्य जिसमें '3' देखा गया है, लेकिन '4' नहीं
  • एक मध्यवर्ती स्थिति जिसमें '4' देखा गया है, लेकिन '3' नहीं
  • एक अंतिम अवस्था जिसमें '3' और '4' दोनों देखी गई हैं

कोई फर्क नहीं पड़ता कि ऑटोमेटन किस स्थिति में है, '1' और '2' पढ़ा जा सकता है; वे मशीन की स्थिति को नहीं बदलते हैं। प्रारंभिक अवस्था में, '3' या '4' भी स्वीकार किया जाएगा; मध्यवर्ती राज्यों में, केवल '4' या '3' स्वीकार किया जाता है; अंतिम स्थिति में, न तो '3' और न ही '4' स्वीकार किया जाता है। नियमित अभिव्यक्ति की संरचना को समझना आसान है यदि हम पहली बार अपनी भाषा के सबसेट के लिए एक रेक्स को परिभाषित करते हैं जिसमें केवल '3' और '4' होते हैं:

(34)|(43)

दिए गए स्थान पर किसी भी संख्या में '1' या '2' की अनुमति देने के लिए, हम सम्मिलित कर सकते हैं (1|2)*(या [12]*यदि हमारी regex भाषा उस संकेतन को स्वीकार करती है)। सभी उपलब्ध स्थानों पर इस अभिव्यक्ति को सम्मिलित करते हुए, हम प्राप्त करते हैं

(1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)*

इसे सामग्री मॉडल में अनुवाद करना सरल है। मूल संरचना रेगेक्स के बराबर है (34)|(43):

<xsd:complexType name="paul0">
  <xsd:choice>
    <xsd:sequence>
      <xsd:element ref="child3"/>
      <xsd:element ref="child4"/>
    </xsd:sequence>
    <xsd:sequence>
      <xsd:element ref="child4"/>
      <xsd:element ref="child3"/>
    </xsd:sequence>
  </xsd:choice>
</xsd:complexType>

शून्य-या-अधिक विकल्प सम्मिलित करना child1और child2सीधा है:

<xsd:complexType name="paul1">
  <xsd:sequence>
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="child1"/>
      <xsd:element ref="child2"/>
    </xsd:choice>      
    <xsd:choice>
      <xsd:sequence>
        <xsd:element ref="child3"/>
        <xsd:choice minOccurs="0" maxOccurs="unbounded">
          <xsd:element ref="child1"/>
          <xsd:element ref="child2"/>
        </xsd:choice>      
        <xsd:element ref="child4"/>
      </xsd:sequence>
      <xsd:sequence>
        <xsd:element ref="child4"/>
        <xsd:choice minOccurs="0" maxOccurs="unbounded">
          <xsd:element ref="child1"/>
          <xsd:element ref="child2"/>
        </xsd:choice>      
        <xsd:element ref="child3"/>
      </xsd:sequence>
    </xsd:choice>
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="child1"/>
      <xsd:element ref="child2"/>
    </xsd:choice>      
  </xsd:sequence>
</xsd:complexType>

हम थोक थोड़ा कम करना चाहते हैं, तो हम का दोहरा विकल्पों के लिए एक नाम वाले समूह को परिभाषित कर सकते हैं child1और child2:

<xsd:group name="onetwo">
  <xsd:choice>
    <xsd:element ref="child1"/>
    <xsd:element ref="child2"/>
  </xsd:choice>   
</xsd:group>

<xsd:complexType name="paul2">
  <xsd:sequence>
    <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:choice>
      <xsd:sequence>
        <xsd:element ref="child3"/>
        <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="child4"/>
      </xsd:sequence>
      <xsd:sequence>
        <xsd:element ref="child4"/>
        <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="child3"/>
      </xsd:sequence>
    </xsd:choice>  
    <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
</xsd:complexType>

XSD 1.1 में, ऑन- allग्रुप्स में से कुछ बाधाओं को हटा दिया गया है, इसलिए इस सामग्री मॉडल को अधिक संक्षिप्त रूप से परिभाषित करना संभव है:

<xsd:complexType name="paul3">
  <xsd:all>
    <xsd:element ref="child1" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:element ref="child2" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:element ref="child3"/>
    <xsd:element ref="child4"/>      
  </xsd:all>
</xsd:complexType>

लेकिन जैसा कि पहले दिए गए उदाहरणों से देखा जा सकता है, all-ग्रुप में ये परिवर्तन वास्तव में भाषा की अभिव्यंजक शक्ति को नहीं बदलते हैं; वे केवल कुछ विशेष प्रकार की भाषाओं की परिभाषा को अधिक सफल बनाते हैं।


3
मुझे XSD 1.0 xs पसंद है: सभी वैकल्पिक।
ट्वीस्ट्रीमोब

8
+1। यह एक उत्कृष्ट उत्तर है और यह अधिक उत्थान के योग्य है।
क्रिस्टोफर लेट

1
बहुत बढ़िया जवाब ! मुझे वास्तव में इस तरह के स्पष्टीकरण पसंद हैं। यह लक्ष्य की उपलब्धि के पीछे के सभी तर्क और तर्क को प्रकट करता है। अब मैं न केवल इस समस्या को हल करना जानता हूं, बल्कि मैंने इसी तरह की समस्याओं को हल करने का एक नया तरीका सीखा। यह समझाते हुए कि राज्य के स्वचालन का उपयोग करना बहुत अच्छा विचार है।
ईजेलेव

3
माइकल, आप कहते हैं, "सभी समूहों के लिए ये परिवर्तन वास्तव में भाषा की अभिव्यंजक शक्ति को नहीं बदलते हैं; वे केवल कुछ प्रकार की भाषाओं की परिभाषा को अधिक रसीला बनाते हैं"। लेकिन अगर आप किसी भी बच्चे के तत्वों की समस्या का सामान्यीकरण करते हैं, तो एक उपसमूह एक बार दिखाई दे सकता है और दूसरा उपसमुच्चय जो किसी भी संख्या में दिखाई दे सकता है, XSD 1.0 समाधान एक दहनशील विस्फोट में निकलेगा, है ना? जबकि XSD 1.1 समाधान साफ ​​रहेगा।
1942 को ebruchez

1
ebruchez, हाँ - सूचक क्षमता , के रूप में मैं शब्द का प्रयोग, एक जैसे नहीं हैं संक्षिप्तता , कॉम्पैक्ट , terseness , या प्रबंधन क्षमता । अभिव्यंजक शक्ति ही पूछती है "क्या यह औपचारिकता इस भाषा को परिभाषित कर सकती है?" यह व्याकरण के आकार के बारे में नहीं पूछता है, या इस बारे में कि क्या कुछ कृत्रिम चीनी इसे छोटा कर देगी। आपके द्वारा उल्लेखित दहनशील विस्फोट का अर्थ है कि सभी समूहों के लिए XSD 1.1 परिवर्तनों के बिना तत्वों के बड़े सेट को संभालना बहुत ही अप्रिय हो जाता है (और बड़े एन के लिए मेमोरी समाप्त हो सकती है)। इसका मतलब यह नहीं है कि वे सिद्धांत रूप में असंभव हो जाते हैं।
CM Sperberg-McQueen

49

यह वही है जो आखिरकार मेरे लिए काम करता है:

<xsd:element name="bar">
  <xsd:complexType>
    <xsd:sequence>
      <!--  Permit any of these tags in any order in any number     -->
      <xsd:choice minOccurs="0" maxOccurs="unbounded">
        <xsd:element name="child1" type="xsd:string" />
        <xsd:element name="child2" type="xsd:string" />
        <xsd:element name="child3" type="xsd:string" />
      </xsd:choice>
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

5
वास्तव में ट्रिक xsd का उपयोग करना है: क्वांटिफायर्स के साथ पसंद करें <xsd: choice minOccurs = "0" maxOccurs = "unbounded">
tivo

6
मुझे लगता है कि यह इंगित करने के लायक है कि उपर्युक्त उदाहरण विकल्प-तत्व को शामिल किए बिना अनुक्रम-तत्व के बिना भी काम करता है।

9

लेकिन जो मैं एक्स को समझता हूं: विकल्प अभी भी केवल एकल तत्व चयन की अनुमति देता है। इसलिए इस तरह से अनधिकृत रूप से मैक्सओर्स को सेट करने का मतलब केवल यह होना चाहिए कि बाल तत्वों का "कोई भी" कई बार दिखाई दे सकता है। क्या यह सही है?

नहीं। चुनाव हर "पुनरावृत्ति" के लिए व्यक्तिगत रूप से होता xs:choiceहै, जिसके कारण होता है maxOccurs="unbounded"। इसलिए, आपके द्वारा पोस्ट किया गया कोड सही है, और वास्तव में वही करेगा जो आप लिखित रूप में चाहते हैं।


@Alan द्वारा दिए गए उत्तर के साथ आपकी टिप्पणी यह ​​सब अच्छी तरह से समझाती है।
बोर

3

आपको यह पता लगाना चाहिए कि निम्नलिखित स्कीमा ने आपके द्वारा प्रस्तावित प्रस्ताव को अनुमति देता है।

  <xs:element name="foo">
    <xs:complexType>
      <xs:sequence minOccurs="0" maxOccurs="unbounded">
        <xs:choice>
          <xs:element maxOccurs="unbounded" name="child1" type="xs:unsignedByte" />
          <xs:element maxOccurs="unbounded" name="child2" type="xs:string" />
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

यह आपको एक फ़ाइल बनाने की अनुमति देगा जैसे:

<?xml version="1.0" encoding="utf-8" ?>
<foo>
  <child1>2</child1>
  <child1>3</child1>
  <child2>test</child2>
  <child2>another-test</child2>
</foo>

जो आपके प्रश्न से मेल खाता प्रतीत होता है।


minOccursऔर maxOccursबच्चों के लिए 1 तक सीमित है xs:all
पावेल मिनेव

पावेल: धन्यवाद ... मैंने अपनी पोस्ट को डबल-चेक करने के बाद इसका पता लगाया और फिर
एक्स

1

यदि उपरोक्त में से कोई भी काम नहीं कर रहा है, तो आप शायद EDI ट्रैसैक्शन पर काम कर रहे हैं, जहाँ आपको HIPPA स्कीमा या उस मामले के लिए किसी अन्य जटिल xsd के विरुद्ध अपना परिणाम मान्य करने की आवश्यकता है। आवश्यकता यह है कि, कहें कि 8 आरईएफ सेगमेंट हैं और उनमें से किसी को किसी भी क्रम में प्रदर्शित होना है और सभी की आवश्यकता भी नहीं है, कहने का मतलब है कि आप उन्हें निम्नलिखित क्रम में 1 आरईएफ, 3 आरईएफ, 2 डीईआरई, 9 वें आरईएफ के बाद कर सकते हैं। डिफ़ॉल्ट स्थिति के तहत ईडीआई प्राप्त विफल हो जाएगा, बीकॉज़ डिफ़ॉल्ट जटिल प्रकार है

<xs:sequence>
  <xs:element.../>
</xs:sequence>

स्थिति तब और भी जटिल हो जाती है जब आप अपने तत्व का खंडन करके बुला रहे होते हैं और फिर मूल तत्व में वह तत्व अपने आप में काफी जटिल होता है। उदाहरण के लिए:

<xs:element>
<xs:complexType>
<xs:sequence>
<element name="REF1"  ref= "REF1_Mycustomelment" minOccurs="0" maxOccurs="1">
<element name="REF2"  ref= "REF2_Mycustomelment" minOccurs="0" maxOccurs="1">
<element name="REF3"  ref= "REF3_Mycustomelment" minOccurs="0" maxOccurs="1">
</xs:sequence>
</xs:complexType>
</xs:element>

उपाय:

यहाँ "सभी" के साथ "अनुक्रम" की जगह या मिनट / अधिकतम संयोजनों के साथ "पसंद" का उपयोग करने से काम नहीं चलेगा!

पहली बात "xs:sequence" with "<xs:all>" अब बदलें , आपको कुछ बदलाव करने की आवश्यकता है जहां आप तत्व का संदर्भ दे रहे हैं, वहां जाएं:

<xs:annotation>
  <xs:appinfo>
    <b:recordinfo structure="delimited" field.........Biztalk/2003">

*** अब उपरोक्त सेगमेंट में इस ट्रिगर_एंड की तरह अंत में ट्रिगर पॉइंट जोड़ें। "REF01 _... पूरा नाम .." ट्रिगर_वल्यू = "38" अन्य आरईएफ सेगमेंट के लिए वही करें जहां ट्रिगर मान अलग-अलग होगा जैसे "18 "," XX "," YY "इत्यादि। जो कि आपकी रिकॉर्ड जानकारी अब दिखता है:b:recordinfo structure="delimited" field.........Biztalk/2003" trigger_field="REF01_...complete name.." trigger_value="38">


यह प्रत्येक तत्व को अद्वितीय बना देगा, कारण यह है कि सभी आरईएफ सेगमेंट (उदाहरण के ऊपर) में REF01, REF02, REF03 जैसी संरचना है। और सत्यापन के दौरान संरचना का सत्यापन ठीक है, लेकिन यह मूल्यों को दोहराने नहीं देता है क्योंकि यह पहले आरईएफ में शेष मूल्यों की तलाश करने की कोशिश करता है। ट्रिगर्स जोड़ने से वे सभी अद्वितीय हो जाएंगे और वे किसी भी क्रम और स्थितिजन्य मामलों में पास हो जाएंगे (जैसे 9 में से 5 का उपयोग करें और सभी 9/9 नहीं)।

आशा है कि यह आपकी मदद करेगा, क्योंकि मैंने इस पर लगभग 20 घंटे बिताए हैं।

शुभ लाभ

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.