2009-10-28 3 views
7

निम्नलिखित XML उदाहरण को देखते हुए हम एक स्कीमा परिभाषित रूट की कल्पना कर सकते हैं जिसमें टाइप 1 और टाइप 2 के बीच विकल्पों की अनबाउंड संख्या का अनुक्रम शामिल है।विकल्पों की अनुक्रम में क्रम को संरक्षित करना (LINQ से XSD)

<Root> 
    <Type1 /> 
    <Type2 /> 
    <Type2 /> 
    <Type1 /> 
</Root> 

मैं XSD.exe उपकरण जो हालांकि टाइप-सुरक्षा थोड़ा खीज का एक बहुत है कहते हैं से पलायन का परीक्षण कर रहा हूँ। इस मामले में एक्सएसडी उपकरण बस रूट के भीतर सिस्टम सिस्टम की एक सरणी बनाता है। ऑब्जेक्ट और आपको यह पता लगाना होगा कि किस प्रकार की ऑब्जेक्ट्स (टाइप 1 या टाइप 2) वहां हैं। यह पूरी तरह से सुरुचिपूर्ण नहीं है, लेकिन कम से कम आप आदेश को संरक्षित करते हैं।

समस्या तब होती है जब LINQ से XSD ऑब्जेक्ट बनाता है, यह रूट को टाइप 1 और टाइप 2 की दो स्वतंत्र सूचियों के रूप में परिभाषित करता है। यह बहुत अच्छा है कि यह टाइप-सुरक्षित है, लेकिन अब मैं तत्वों का क्रम खोना प्रतीत होता हूं। मैंने कोडप्लेक्स पर स्रोत से LINQ से XSD बनाया।

LINQ से XSD का उपयोग करके, मैं इन तत्वों के क्रम को कैसे संरक्षित कर सकता हूं?

+3

ठीक है, आप पहले से ही केवल दो विकल्प प्रस्तुत कर चुके हैं। या तो आपको एक कमजोर टाइप किया गया संग्रह मिलता है जो ऑर्डर को सुरक्षित रखता है, या आपको प्रति प्रकार एक दृढ़ता से टाइप किया गया संग्रह मिलता है। दिखाओ कि आप किसी भी एक्सएमएल का उपयोग नहीं कर रहे हैं - आप एक शुद्ध-कोड ऑब्जेक्ट कैसे लिखेंगे जिसमें एक प्रकार का दृढ़ता से टाइप किया गया संग्रह है जिसमें कई प्रकार हैं? –

+0

मेरा प्रश्न यह है कि लिंक से एक्सएसडी का उपयोग करके इस परिदृश्य में तत्वों के क्रम को कैसे संरक्षित किया जाए। मुझे लगता है कि मिश्रित प्रकारों का संग्रह होना चाहिए जिन्हें उन्हें सिस्टम की आवश्यकता होगी। ऑब्जेक्ट (या जो भी माता-पिता उनके समान हैं)। मैं आदेश को संरक्षित करने के लिए इस परिदृश्य w/Linq से XSD में दृढ़ता से टाइप की गई वस्तुओं को छोड़ने के लिए तैयार हूं। मैं उम्मीद कर रहा था कि ऐसा करने के लिए मजबूर करने का एक तरीका था। मेरे उपयोग के मामले में, ऑर्डर मायने रखता है, इसलिए मैं लिंक से एक्सएसडी का उपयोग नहीं कर सका, हालांकि मैं वास्तव में ऐसा करना चाहता हूं क्योंकि XSD.exe – Philip

+6

पर इसके कई फायदे हैं, आप इसे विरासत के साथ कर सकते हैं। यदि टाइप 1 और टाइप 2 दोनों में एक सामान्य बेस क्लास था, तो आपके पास एक IList हो सकता है। अब आपके पास एक एकल, दृढ़ता से टाइप की गई सूची है, और ऑर्डर संरक्षित है।सूची के माध्यम से पुनरावृत्ति करते समय, बस वर्तमान वस्तु के प्रकार की जांच करें। foreach (तत्वों में BaseType एल) { अगर (एल टाइप 1 है) ... else if (एल Type2 है) ... } –

उत्तर

2

चॉइस के चारों ओर एक रैपर बनाने के बारे में कैसे? प्रकार है कि इसे इस तरह पहुँचता सीमित:

class Choice 
{ 
    private object _value; 

    public ChoiceEnum CurrentType { get; private set; } 

    public Type1 Type1Value 
    { 
     get { return (Type1) _value; } 
     set { _value = value; CurrentType = ChoiceEnum.Type1; } 
    } 

    public Type2 Type2Value 
    { 
     get { return (Type2) _value; } 
     set { _value = value; CurrentType = ChoiceEnum.Type2; } 
    } 
} 

यह एक सरलीकृत संस्करण है, और आप अधिक मान्यता जोड़ना होगा (अगर _value सही प्रकार की है, _value की वर्तमान प्रकार, आदि क्या है)।

उसके बाद, आप यह LINQ के साथ फ़िल्टर कर सकते हैं:

var q1 = from v in root.Sequence 
     where v.CurrentType == ChoiceEnum.Type1 
     select v.Type1; 

या आप रूट में तरीकों कि प्रश्नों लपेट बना सकते हैं।

+0

अच्छा सुझाव। यह काम करना चाहिए, लेकिन एक्सएसडी के डिजाइन को निर्देशित करता है जो दुर्भाग्यपूर्ण है, और कभी-कभी असंभव (उदाहरण के लिए उद्योग मानक स्कीमा)। हमारी टीम पर हमारे द्वारा बनाई गई कई योजनाएं हमारे द्वारा बनाई गई हैं, इसलिए हम इस तकनीक का उपयोग करने में सक्षम हो सकते हैं। – Philip

1

लिंक 2Xsd केवल xsd: पसंद तत्व होने पर अनुक्रमों पर यात्रा करता है।

सौभाग्य से मैं XSD को दूर करने में सक्षम था: Amazon XSD के लिए पसंद मैं उपयोग कर रहा हूँ (मैं सिर्फ MerchantOrderID का उपयोग नहीं किया गया था) है, जिसकी अनुमति अनुक्रम ठीक से एक्सएमएल के लिए ToString() में संरक्षित किया जाना है।

  <xsd:choice>        <--- removed line 
       <xsd:element ref="AmazonOrderID"/> 
       <xsd:element ref="MerchantOrderID"/> <--- removed line 
      </xsd:choice>        <--- removed line 

      <xsd:element name="ActionType" minOccurs="0" maxOccurs="1"> 
       <xsd:simpleType> 
        <xsd:restriction base="xsd:string"> 
         <xsd:enumeration value="Refund"/> 
         <xsd:enumeration value="Cancel"/> 
        </xsd:restriction> 
       </xsd:simpleType> 
      </xsd:element> 

उत्पन्न कोड तो सही ढंग से निर्माता जो आदेश

contentModel = new SequenceContentModelEntity(
       new NamedContentModelEntity(XName.Get("AmazonOrderID", "")), 
       new NamedContentModelEntity(XName.Get("ActionType", "")), 
       new NamedContentModelEntity(XName.Get("CODCollectionMethod", "")), 
       new NamedContentModelEntity(XName.Get("AdjustedItem", ""))); 

आप भी इसे अपने आप उपवर्गीकरण करके स्वयं भी यह करने के लिए सक्षम हो सकता है को बरकरार रखता है में इस है, लेकिन मैं कर रहा हूँ यह सुनिश्चित नहीं है कि यह xsd: पसंद के साथ कैसे काम करेगा। यह described here है लेकिन मैंने इसका परीक्षण नहीं किया है।

संबंधित मुद्दे