2011-12-27 23 views
5

मेरे पास एक ऑब्जेक्ट स्ट्रक्चर है जो मैं एक्सएमएल को क्रमबद्ध करने की कोशिश कर रहा हूं जिसके परिणामस्वरूप डुप्लिकेट नोड स्तर होता है। मुझे पूरा यकीन है कि इसमें सबक्लासिंग के साथ कुछ करना है क्योंकि मुझे अपना खुद का deserialization लागू करना था, लेकिन मुझे यकीन नहीं है कि दूसरी दिशा में क्या हो रहा है। वही एक्सएमएल संरचना इनपुट के रूप में उपयोग की जाती है जब एप्लिकेशन लॉन्च पर मेरे डेटा को deserializing जब इसे बाद में सहेजने के लिए reserializing।एक्सएमएल सीरियलाइजेशन परिणाम डुप्लिकेट नोड्स

<Keyboarding xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Exercises> 
    <Exercise> 
     <Exercise Id="3" ActivityNumber="5" SubActivityNumber="b" Type="Standard"> 
     <Title>Test Title</Title> 
     <Instructions>Downloaded Update Instructions</Instructions> 
     </Exercise> 
    </Exercise> 
    </Exercises> 
</Keyboarding> 

यहाँ क्या यह कैसा दिखना चाहिए (और प्रारंभिक अक्रमांकन पर तरह दिखता है):

<Keyboarding xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Exercises> 
     <Exercise Id="3" ActivityNumber="5" SubActivityNumber="b" Type="Standard"> 
     <Title>Test Title</Title> 
     <Instructions>Downloaded Update Instructions</Instructions> 
     </Exercise> 
    </Exercises> 
</Keyboarding> 

जड़ वस्तु अभ्यास का संग्रह होता

यहाँ दोषपूर्ण उत्पादन एक्सएमएल लग रहा है की तरह है । व्यायाम मेरी बेस क्लास है, जबकि उप-वर्ग टाइप विशेषता द्वारा निर्धारित किए जाते हैं। मैं व्यायाम से भिन्न व्युत्पन्न प्रकारों की वस्तुओं का निर्माण करने के लिए एक कस्टम एक्सएमएल सीरिएलाइज़र का उपयोग कर रहा हूं क्योंकि यह मुझे 2 दर्जन या उससे अधिक संभावित व्युत्पन्न प्रकारों से मेल खाने के लिए प्रतिबिंब का उपयोग करने की अनुमति देता है, जो अज्ञात क्रम में होते हैं और मात्रा में पहली बार पढ़ते समय मेरे आवेदन से।

यहाँ मूल तत्व का संग्रह है, कस्टम एक्सएमएल serializer का उपयोग कर:

[XmlArray("Exercises")] 
[XmlArrayItem("Exercise", Type = typeof (ExerciseXmlSerializer<Exercise>))] 
public Collection<Exercise> UnprocessedExercises { get; set; } 

मेरे आधार व्यायाम वर्ग इस प्रकार घोषित किया जाता है:

[Serializable] 
[XmlType(AnonymousType = true)] 
public class Exercise 

और मेरे व्युत्पन्न वर्ग घोषित किया जाता है इस प्रकार है:

[Serializable] 
[XmlType(AnonymousType = true)] 
[XmlRoot(ElementName = "Exercise", IsNullable = false)] 
public class StandardExercise : Exercise 

यहां मेरे कस्टम एक्सएमएल सीरिएलाइज़र का लेखक भाग है:

public class ExerciseXmlSerializer<T> : IXmlSerializable where T : class 
{ 
    private T _data; 
    ... 
    public void WriteXml(XmlWriter writer) 
    { 
     Type type = _data.GetType(); 

     new XmlSerializer(type).Serialize(writer, _data); 
    } 
    ... 
} 

विधि WriteXml() में, प्रकार चर ठीक से व्युत्पन्न प्रकार के लिए सेट है, तो क्यों यह दोनों आधार प्रकार और व्युत्पन्न प्रकार के लिए एक नोड स्तर बनाता है? मैं इसे ऐसा करने से कैसे रोकूं?

उत्तर

1

मुझे लगता है कि आपकी समस्या को इस लाइन के साथ है:

[XmlArrayItem("Exercise", Type = typeof (ExerciseXmlSerializer<Exercise>))] 

मुझे नहीं लगता कि आप संकेत मिलता है कि आइटम के प्रकार serializer का एक प्रकार है चाहते हैं। यदि आप IXmlSerializable को कार्यान्वित करना चाहते हैं, तो इसे क्रमबद्ध करने के लिए कक्षा पर होना आवश्यक है।

<?xml version=\"1.0\"?> 
<Keyboarding xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"> 
    <Exercises> 
    <Exercise xsi:type=\"StandardExercise\" /> 
    </Exercises> 
</Keyboarding> 

आप xsi:type उत्पादन में शामिल नहीं करना चाहते हैं, तो आप उपयोग कर सकते हैं:

public class Keyboarding 
{ 
    [XmlArray("Exercises")] 
    [XmlArrayItem("Exercise")] 
    public Collection<Exercise> UnprocessedExercises { get; set; } 

    public Keyboarding() 
    { 
     UnprocessedExercises = new Collection<Exercise>(); 
     UnprocessedExercises.Add(new StandardExercise()); 
    } 
} 

[XmlInclude(typeof(StandardExercise))] 
public class Exercise 
{ 
} 
[Serializable] 
public class StandardExercise : Exercise 
{ 
} 

यह निम्न के समान उत्पादन का उत्पादन:

यहाँ मैं क्या काम मिल गया है this question का उत्तर।

+0

जब मैं प्रारंभिक डेटा को deserialize करने की कोशिश कर रहा हूं, तो इस तरह के ब्रेक के रूप में स्वरूपण, जिसमें एक ही एक्सएमएल प्रारूप है। जब मैंने कोड से मिलान करने के लिए कोड और प्रारंभिक एक्सएमएल को संशोधित किया, तो यह सभी प्रकार के सबक्लासिंग को खोने और खोने पर मूल प्रकार के रूप में टाइप किया गया। मैं आइटम्स के प्रकार को एक्सएमएल सीरियलाइज़र के रूप में निर्दिष्ट कर रहा था क्योंकि एक्सएमएल में लगभग 2 दर्जन संभावित व्युत्पन्न कक्षाएं टाइप की जा सकती हैं और वस्तुओं और ऑर्डर की अज्ञात संख्या होती है। यह मुझे व्युत्पन्न वस्तुओं को बनाने के लिए टाइप विशेषता लेने और मेरे कस्टम धारावाहिक में प्रतिबिंब का उपयोग करने देता है। थोड़ा सा स्पष्टीकरण देने के लिए मैं अपना प्रश्न संपादित करूंगा। – HotN

+1

@HotN: क्या आपने सीधे व्यायाम कक्षा में अपने कस्टम सीरियलाइजेशन कोड को लागू करने का प्रयास किया है? जब मैं कोड को चलाने की कोशिश करता हूं तो मुझे अपवाद मिलते हैं और यह XmlArrayItem में यह टाइप टाइप (ExerciseXmlSerializer ) है जो समस्याओं का कारण बन रहा है। आप मेरे उत्तर के अंत में जुड़े प्रश्न के उत्तर में दिखाए गए कस्टम xmlwriter लिखने का भी प्रयास कर सकते हैं। –

+0

समस्या निश्चित रूप से 'टाइपऑफ (एक्सरसाइज एक्सएमएलएसरिएलाइज़र )' भाग के कारण हुई थी, लेकिन मुझे जो मिला वह यह है कि केवल व्यायाम करने के लिए इसे क्रमबद्ध करने की समस्या हल हो जाएगी, लेकिन व्युत्पन्न वर्ग प्रकारों को एक विशेषता द्वारा निर्धारित किया गया था क्योंकि मेरे deserialization तोड़ देगा। मैंने अभ्यास संग्रह के लिए मूल कोड को छोड़कर अंत में काम करने के लिए इसे प्राप्त किया लेकिन जैसा कि आपने सुझाव दिया था, अपने स्वयं के XmlTextWriter को लागू करना। यह एक तरह का घुलनशील समाधान की तरह लगता है, लेकिन मुझे ऐसा लगता है कि मुझे 20 व्युत्पन्न कक्षाओं को [XmlInclude] के रूप में सूचीबद्ध करने की आवश्यकता नहीं थी। वैसे भी, परिणाम परिणाम हैं। धन्यवाद! – HotN

0

आप XmlAttributeOverrides उपयोग करने के लिए आप क्या कह रहे हैं ऐसा करने में सक्षम होना चाहिए। इस मामले में, आप शायद ऐसा कुछ करेंगे। नमूना कोड थोड़ा मोटा है क्योंकि आपने अपना संपूर्ण ऑब्जेक्ट ग्राफ़ शामिल नहीं किया है, लेकिन उम्मीद है कि यह आपको सही दिशा में इंगित करेगा।

List<Type> extraTypes = new List<Type>(); 
XmlAttributes attrs = new XmlAttributes(); 

extraTypes.Add(typeof(Exercise)); 
extraTypes.Add(typeof(StandardExercise)); 

XmlElementAttribute attr = new XmlElementAttribute 
{ 
    ElementName = "Exercise", 
    Type = typeof(Exercise) 
}; 
attrs.XmlElements.Add(attr); 

attr = new XmlElementAttribute 
{ 
    ElementName = "StandardExercise", 
    Type = typeof(StandardExercise) 
}; 
attrs.XmlElements.Add(attr); 

XmlAttributeOverrides overrides = new XmlAttributeOverrides(); 
overrides.Add(typeof(Keyboarding), "Keboarding", attrs); 

return new XmlSerializer(typeof(Keyboarding), overrides, extraTypes.ToArray(), 
    new XmlRootAttribute("Keyboarding"), string.Empty); 

इससे आपको ऐसा लगता है कि एक XML पेड़ बनाने की अनुमति देनी चाहिए। यह काफी नहीं है जिसे आप ढूंढ रहे थे, लेकिन यह वर्णनात्मक है।

<Keyboarding xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Exercises> 
     <StandardExercise Id="3" ActivityNumber="5" SubActivityNumber="b"> 
      <Title>Test Title</Title> 
      <Instructions>Downloaded Update Instructions</Instructions> 
     </StandardExercise > 
    </Exercises> 
</Keyboarding> 
संबंधित मुद्दे