2011-10-06 17 views
5

में कनवर्ट करना मेरे पास एक xsd फ़ाइल है जिसमें से मैं एक सी # कक्षा उत्पन्न कर रहा हूं। आसान रखरखाव प्रदान करने के लिए, मैं केवल xsd फ़ाइल के भीतर एक गणना परिभाषित करना चाहता हूं ताकि जब मुझे enum को बदलना पड़े, तो मुझे केवल इसे एक ही स्थान पर अपडेट करना होगा। मैं enum बनाने के लिए कैसे पता है, लेकिन जब सी # कोड उत्पन्न होता है, मैं enum सदस्यों की जरूरत कस्टम मानों के लिए है, इसलिए परिणाम के समान होगा:xsd enums को C#

public enum SetupTypeEnum { 
    None = 0, 
    NewInstall = 1, 
    Modify = 2, 
    Upgrade = 4, 
    Uninstall = 8 
} 

वहाँ किसी भी तरह से करने के लिए XSD लिखने के लिए है इसे पूरा करो?

+0

क्या आप सी # कोड उत्पन्न करने के लिए अपना स्वयं का टूल लिख रहे हैं, या क्या कोई मानक उपकरण है जो एक्सएसडी से सी # कोड उत्पन्न करता है? – BlueMonkMN

+0

अभी मैं xsd.exe का उपयोग कर रहा हूं। मेरे पास वास्तव में अपना खुद का टूल बनाने का समय नहीं है। –

उत्तर

6

आप कोड पीढ़ी के लिए विशिष्ट एनोटेशन जोड़ सकते हैं (यह केवल xsd.exe के लिए नहीं, svsil के लिए काम करता है) आपके xsd फ़ाइल में।

<xs:simpleType name="SetupTypeEnum"> 
    <xs:restriction base="xs:string"> 
     <xs:enumeration value="None"> 
      <xs:annotation> 
       <xs:appinfo> 
        <EnumerationValue xmlns="http://schemas.microsoft.com/2003/10/Serialization/">0</EnumerationValue> 
       </xs:appinfo> 
      </xs:annotation> 
     </xs:enumeration> 
     <xs:enumeration value="NewInstall"> 
      <xs:annotation> 
       <xs:appinfo> 
        <EnumerationValue xmlns="http://schemas.microsoft.com/2003/10/Serialization/">1</EnumerationValue> 
       </xs:appinfo> 
      </xs:annotation> 
     </xs:enumeration> 
     ... 
    </xs:restriction> 
</xs:simpleType> 

ये टिप्पणियां आप स्पष्ट रूप से प्रत्येक enum मूल्य के संख्यात्मक मान निर्धारित करने की अनुमति: अपने enum के लिए XSD परिभाषा कुछ इस तरह होगा। यदि आप "EnumerationValue" खोजते हैं तो आप एक उदाहरण on this msdn page पा सकते हैं।

अद्यतन: जॉन सॉंडर्स अपनी टिप्पणी में सही ढंग से बताते हैं कि यदि आप xsd.exe का उपयोग करते हैं तो यह काम नहीं करता है। हालांकि, यदि आप सी # कोड बनाने के लिए svcutil.exe का उपयोग करते हैं, तो एनोटेशन काम करेंगे।

svcutil.exe का उपयोग करने का उदाहरण:

svcutil /dconly "D:\test.xsd" /o:"D:\test.cs" 

आप xsd.exe के बजाय svcutil उपयोग करते हैं, तो उत्पन्न कोड थोड़ा अलग करके होगा। सबसे महत्वपूर्ण अंतर यह है कि svcutil XmlSerialization के बजाय DataContractSerialization के लिए विशेषताओं को उत्पन्न करेगा।

+0

-1: दिलचस्प लिंक, और मुझे इस सुविधा के बारे में पता नहीं था; लेकिन यदि ओपी XSD.EXE का उपयोग कर रहा है, तो वह एक्सएमएल सीरियलाइजेशन का उपयोग कर रहा है, और 'एन्युमरेशन वैल्यू' डेटा अनुबंध सीरिएलाइज़र की एक विशेषता है। –

+0

@ जॉन: हाँ, यह सच है कि यह डेटा अनुबंध धारावाहिक के लिए है, मैंने सोचा कि यह 'xsd.exe' के लिए भी काम करेगा। हालांकि, यदि आप xsd फ़ाइल से कोड बनाने के लिए 'svcutil' का उपयोग करते हैं, तो एनोटेशन काम करते हैं। –

+0

कारण मैं xsd का उपयोग कर रहा हूं क्योंकि मुझे एहसास नहीं हुआ कि मैं इसे किसी अन्य तरीके से कर सकता हूं। हालांकि यह अधिक कोडिंग हो सकता है जितना मैं इसमें डालना चाहता हूं, जवाब वास्तव में जो मैं ढूंढ रहा हूं उसके लिए बिल्कुल सही है। –

1

चेक यदि यह आप में मदद करता है:

XSD Definition for Enumerated Value

http://wizzup.wordpress.com/2009/02/19/how-to-define-enumeration-in-xsd/

+0

जो प्रत्येक मान के साथ विशिष्ट संख्यात्मक मानों को जोड़ने की अनुमति नहीं देता है। – BlueMonkMN

+0

धन्यवाद, लेकिन मैं पहले से ही इसे प्राप्त कर लिया है। चूंकि BlueMonkMN ने कहा, यह संबद्ध मूल्यों की अनुमति नहीं देता है। –

+0

इस लिंक को चेक करें: http://bytes.com/topic/net/answers/85686-xml-chechema-enumeration-question –

2

मेरा मानना ​​है कि XSD enumerations भावना है कि वे की जरूरत है और डॉन नहीं है में नेट enumerations से enumerations का एक और अधिक शुद्धतावादी कार्यान्वयन कर रहे हैं गणना किए गए नामों से जुड़े संख्यात्मक मूल्यों का समर्थन नहीं करते हैं। निस्संदेह जेनरेट कोड, .NET कोड होने के साथ, आंतरिक रूप से प्रत्येक नामित मान के साथ एक संख्यात्मक मान को जोड़ देगा, लेकिन यह एक कार्यान्वयन विवरण है जो एक्सएसडी मानक द्वारा परिभाषित गणना की प्रकृति के लिए निहित नहीं है। एक गणना के इस शुद्ध कार्यान्वयन में, मेरा मानना ​​है कि प्रत्येक संख्याबद्ध नाम के साथ स्पष्ट संख्यात्मक मानों को जोड़ने का उचित तरीका एक अलग संग्रह/वर्ग को परिभाषित करना होगा जो संख्यात्मक मानों को संख्यात्मक मानों से जोड़ता है। या अतिरिक्त समेकित मानों को परिभाषित करें जो आपके द्वारा समर्थित संयुक्त मानों का प्रतिनिधित्व करते हैं (NewInstallOrModify)।

संपादित करें:

यहाँ एक कनवर्टर दिखाई देती हैं इसका एक नमूना है।

// Generated code 
public enum SetupTypeEnum 
{ 
    None, 
    NewInstall, 
    Modify, 
    Upgrade, 
    Uninstall 
} 
// End generated code 

public struct IntMappedEnum<T> where T : struct 
{ 
    public readonly int originalValue; 

    public IntMappedEnum(T value) 
    { 
    originalValue = (int)Enum.ToObject(typeof(T), value); 
    } 

    public IntMappedEnum(int originalValue) 
    { 
    this.originalValue = originalValue; 
    } 

    public static implicit operator int(IntMappedEnum<T> value) 
    { 
    return 1 << value.originalValue; 
    } 

    public static implicit operator IntMappedEnum<T>(T value) 
    { 
    return new IntMappedEnum<T>(value); 
    } 

    public static implicit operator IntMappedEnum<T>(int value) 
    { 
    int log; 
    for (log = 0; value > 1; value >>= 1) 
     log++; 
    return new IntMappedEnum<T>(log); 
    } 

    public static explicit operator T(IntMappedEnum<T> value) 
    { 
    T result; 
    Enum.TryParse<T>(value.originalValue.ToString(), out result); 
    return result; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
    SetupTypeEnum s = SetupTypeEnum.Uninstall; 
    IntMappedEnum<SetupTypeEnum> c = s; 
    int n = c; 
    IntMappedEnum<SetupTypeEnum> c1 = n; 
    SetupTypeEnum s1 = (SetupTypeEnum)c1; 
    Console.WriteLine("{0} => {1} => {2}", s, n, s1); 
    } 
} 

संपादित करें 2:

अपने enum (के रूप में अपने उदाहरण है) इन दो परिवर्तन मेरी उदाहरण के लिए आवश्यक हैं 0 पर शुरू होता है:

अपडेट किया गया पूर्णांक कनवर्टर:

public static implicit operator int(IntMappedEnum<T> value) 
{ 
    return (value.originalValue == 0)?0:1 << (value.originalValue - 1); 
} 

int log के बाद की रेखा होनी चाहिए:

for (log = 0; value > 0; value >>= 1) 
+0

धन्यवाद। क्या आपके पास एक लिंक है जो एक वर्ग का नमूना दिखाएगा जो मूल्यों को लिंक करेगा? –

+0

@ ड्रू बुर्चेट: यह इस बात पर निर्भर करता है कि आप इसका उपयोग कैसे करेंगे, लेकिन मैंने कोड जोड़ा है जो आपके उदाहरण के लिए काम करता है और मानता है कि आप अन्य गणनाओं को 2 की शक्तियों के समान प्रतिनिधित्व करना चाहते हैं। – BlueMonkMN

2

एक्सएसडी में "गणना" की अवधारणा के पास सी # में "enum" की अवधारणा से कोई लेना देना नहीं है।

एक्सएमएल स्कीमा में "गणना" एक प्रकार के संभावित शब्दावली मूल्यों को पर मानों की सूची को प्रतिबंधित करने का एक तरीका है। उदाहरण के लिए:

<xs:simpleType name="SummerMonth"> 
    <xs:restriction base="xs:gMonth"> 
     <xs:enumeration value="--07"/> 
     <xs:enumeration value="--08"/> 
     <xs:enumeration value="--09"/> 
    </xs:restriction> 
</xs:simpleType> 

इस प्रकार मूल्य स्थान को "ग्रीष्मकालीन" महीनों (जुलाई, अगस्त और सितंबर) के सेट पर प्रतिबंधित करता है।

स्पष्ट रूप से, इसका सी # या किसी अन्य प्रोग्रामिंग भाषा में "enum" के लिए कोई पत्राचार नहीं है।

+0

जबकि मैं समझता हूं कि आप ' फिर से कह रहा है, xsd.exe एक xsd गणना को सी # गणना में परिवर्तित कर देगा, इसलिए कुछ सहसंबंध है। यह उतना गहरा नहीं जाता जितना कि मैं उम्मीद करता था। –

+0

यह _some_ xsd enumerations को 'enum' में परिवर्तित करेगा। और यहां तक ​​कि, केवल डिफ़ॉल्ट मानों के साथ। –

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