2009-07-20 21 views
12

मुझे बूलियन मानों के साथ एक एक्सएमएल फ़ाइल को deserializing के साथ कोई समस्या है। स्रोत एक्सएमएल फाइल जो मैं deserializing कर रहा हूँ एक वीबी 6 ऐप से बनाया गया था, जहां सभी बुलियन मूल्य पूंजीकृत हैं (True, False)। जब मैं एक्सएमएल deserialize करने की कोशिश, मैं एकएक्सएमएल सीरियलाइजेशन बनाम "ट्रू" और "झूठा"

System.FormatException: The string 'False' is not a valid Boolean value. 

हो रही है वहाँ एक विशेषता के साथ मामले को अनदेखा कहने का एक तरीका है?

उत्तर

5

आप स्ट्रिंग फ़ील्ड में एक स्ट्रिंग के रूप में उस मान को पढ़ सकते हैं, उसके बाद एक रीडोनली बूल फ़ील्ड है जिसमें बूल सत्य या गलत लौटने के लिए इसमें कोई कथन है।

उदाहरण के लिए (ग # का उपयोग कर):

public bool str2bool(string str) 
{ 
    if (str.Trim().ToUpper() == "TRUE") 
     return true; 
    else 
     return false; 
} 

और आप टेम्पलेट में इसका इस्तेमाल कर सकते हैं: सही है या गलत उपयोग करने के बजाय

<xsl:if test="user:str2bool($mystr)"> 
+1

आपको इसका एक उदाहरण शामिल करना चाहिए। यदि आप करते हैं तो आपको शायद सबसे अच्छा सुझाव मिल गया है। –

1

मुझे नहीं लगता कि वहां है। आप इसे स्ट्रिंग कर सकते हैं और ignoreCase मान को सत्य पर सेट करके (String.Compare) तुलना कर सकते हैं।

3

ऐसा नहीं है। एक्सएमएल सीरिएलाइज़र एक्सएमएल स्कीमा के साथ काम करता है, और "ट्रू" और "गलत" मान्य बूलियन नहीं हैं।

आप या तो इन दो मानों को परिवर्तित करने के लिए एक एक्सएमएल ट्रांसफॉर्म का उपयोग कर सकते हैं, या आप IXmlSerializable इंटरफेस को कार्यान्वित कर सकते हैं और अपने आप को क्रमबद्धता और deserialization कर सकते हैं।

+0

आप सही जॉन हैं, तो जब आप दोपहर का खाना खाने से पहले जवाब देते हैं तो क्या होता है: \ .. लेकिन एक्सएमएल ट्रांसफॉर्म के आपके सुझाव को निष्पक्ष होने के लिए संभावित रूप से एक ऐसे मूल्य को भी बदल सकता है जो बूलियन होने का इरादा नहीं है। –

+0

असल में, नहीं। मैं उसे स्पष्ट रूप से विशेषताओं और/या तत्वों को संदर्भित करता हूं जो बुलियन हैं। मेरा मतलब हर विशेषता को बदलने का नहीं था। –

+0

जॉन को समझ लिया। –

5

, 0 का उपयोग करें या 1. यह के लिए काम करेंगे बूलियन।

4

another stack overflow question के आधार पर आप कर सकते हैं:

[XmlIgnore] 
    public bool BadBoolField { get; set; } 

    [XmlAttribute("badBoolField")] 
    public string BadBoolFieldSerializable 
    { 
     get 
     { 
      return this.BadBoolField.ToString(); 
     } 
     set 
     { 
      this.BadBoolField= Convert.ToBoolean(value); 
     } 
    } 

बारे में पता यह है रहें:

public class MySerilizedObject 
{ 
    [XmlIgnore] 
    public bool BadBoolField { get; set; } 

    [XmlElement("BadBoolField")] 
    public string BadBoolFieldSerialize 
    { 
     get { return this.BadBoolField ? "True" : "False"; } 
     set 
     { 
      if(value.Equals("True")) 
       this.BadBoolField = true; 
      else if(value.Equals("False")) 
       this.BadBoolField = false; 
      else 
       this.BadBoolField = XmlConvert.ToBoolean(value); 
     } 
    } 
} 
0

मैं एक ही मुद्दे पर ठोकर खाई है, और Jman द्वारा उत्तर के आधार पर, मैं इसे इस तरह से हल एक्सएमएल/सीरियलाइजेशन विनिर्देश द्वारा जरूरी नहीं है, लेकिन यह अच्छा काम करता है और यह एक व्यापक रूपांतरण मान (यानी "ट्रू", "सत्य" जैसे स्ट्रिंग को संभाल सकता है, यदि आप एक स्ट्रिंग होने की बाधा को प्रतिस्थापित करेंगे तो यह संख्याओं को भी संभाल सकता है)।

0

यहां पाया गया एक और क्लीनर समाधान है जो मैंने पाया कुछ अन्य प्रश्नों के आधार पर आया था।

public class MyXMLClass 
{ 
    public SafeBool Bool { get; set; } 
    public SafeBool? OptionalBool { get; set; } 
} 

आप यहां तक ​​कि उन्हें वैकल्पिक कर सकते हैं और यह सब सिर्फ काम करता है: यह अधिक स्वच्छ क्योंकि तब आप SafeBool के रूप में प्रकार की घोषणा, इस तरह छोड़कर अपने कोड में कुछ भी करने की जरूरत नहीं है। यह सेफबूल संरचना सत्य/झूठी, हां/नहीं या वाई/एन के किसी भी केस प्रकार को संभाल लेगी। यह हमेशा सत्य/झूठी के रूप में क्रमबद्ध होगा, हालांकि मेरे पास अन्य समान structs हैं जो मैं विशेष रूप से वाई/एन या हां/नहीं के रूप में क्रमबद्ध करने के लिए उपयोग करता हूं जब स्कीमा की आवश्यकता होती है (यानी: बूलिन, बूलियसनो structs)।

using System.Xml; 
using System.Xml.Schema; 
using System.Xml.Serialization; 

namespace AMain.CommonScaffold 
{ 
    public struct SafeBool : IXmlSerializable 
    { 
     private bool _value; 

     /// <summary> 
     /// Allow implicit cast to a real bool 
     /// </summary> 
     /// <param name="yn">Value to cast to bool</param> 
     public static implicit operator bool(
      SafeBool yn) 
     { 
      return yn._value; 
     } 

     /// <summary> 
     /// Allow implicit cast from a real bool 
     /// </summary> 
     /// <param name="b">Value to cash to y/n</param> 
     public static implicit operator SafeBool(
      bool b) 
     { 
      return new SafeBool { _value = b }; 
     } 

     /// <summary> 
     /// This is not used 
     /// </summary> 
     public XmlSchema GetSchema() 
     { 
      return null; 
     } 

     /// <summary> 
     /// Reads a value from XML 
     /// </summary> 
     /// <param name="reader">XML reader to read</param> 
     public void ReadXml(
      XmlReader reader) 
     { 
      var s = reader.ReadElementContentAsString().ToLowerInvariant(); 
      _value = s == "true" || s == "yes" || s == "y"; 
     } 

     /// <summary> 
     /// Writes the value to XML 
     /// </summary> 
     /// <param name="writer">XML writer to write to</param> 
     public void WriteXml(
      XmlWriter writer) 
     { 
      writer.WriteString(_value ? "true" : "false"); 
     } 
    } 
} 
+0

मेरी खोज देखें और उत्तर बदलें। आपके पास बहुत सारे कोड हैं जो बेहतर ओ (एन) हो सकते हैं, लेकिन कभी-कभी समस्या को रॉस पेरोट समाधान की आवश्यकता होती है। हुड खोलें और इसे ठीक करें। –

-1

एक टूटी हुई एक्सएमएल प्रणाली को ठीक करने या XmlSerializer से लड़ने को परेशान न करें, खासतौर पर कुछ छोटे के लिए। यह इसके लायक नहीं है। वीबी 6 जल्द ही वापस नहीं आ रहा है।

इसके बजाए, इसे deserialized से पहले दस्तावेज़ को पकड़ लें और मानों को बदलें। यदि आप टैग के बाहर उन्हें बदलने के बारे में चिंतित हैं, तो नियमित अभिव्यक्तियों का उपयोग करें या मानों में कोण ब्रैकेट शामिल करें।

xml = xml.Replace("True", "true").Replace("False", "false"); 

यह भव्यता के लिए किसी भी पुरस्कार जीतने के लिए नहीं जा रहा है, लेकिन यह आप काम करने के लिए वापस हो जाता है। कभी-कभी आपको इसे नीला कॉलर करना पड़ता है।

प्रदर्शन के लिए, हाँ, आप स्ट्रिंग ओ (एन) के माध्यम से दोहरा रहे हैं, लेकिन चूंकि प्रतिस्थापन तार समान लंबाई हैं, इसलिए इसे किसी भी चलती स्ट्रिंग तत्वों की आवश्यकता नहीं होती है। इसके अलावा, कार्यान्वयन के आधार पर, XmlSerializer को संशोधित करने में अधिक ओवरहेड हो सकता है।

+0

आप मानते हैं कि आपके पास एक खोज करने और प्रतिस्थापित करने में सक्षम होने के लिए मूल HTML तक आसानी से पहुंच है, इसलिए आपका उत्तर अच्छा नहीं है। उल्लेख नहीं है कि एक्सएमएल पैकेट बड़ा है, तो आपका कोड दो बार एक विशाल अस्थायी स्ट्रिंग का उत्पादन करने जा रहा है, क्योंकि .NET में स्ट्रिंग अपरिवर्तनीय हैं। –

+0

@ केंडलबेनेट अच्छी तरह से आप यह भी मानते हैं कि उनके पास कक्षाओं तक पहुंच है? मैंने कभी ऐसा मामला नहीं देखा है जहां आप XML इनपुट तक पहुंच के बिना डेटा को deserialize कर सकते हैं। यदि आप वास्तव में प्रदर्शन और स्मृति के बारे में चिंतित हैं, तो आपको वास्तव में XmlSerializer का उपयोग करने से बचना चाहिए क्योंकि यह प्रतिबिंब का उपयोग करता है जो .NET में सबसे महंगा संचालन में से एक है। मेरे समाधान के बारे में कुछ भी नहीं है जो कहता है कि यह स्ट्रीमिंग डेटा पर काम नहीं कर सकता है। मेरा मुद्दा यह है कि बेवकूफ कार्यान्वयन कभी-कभी सबसे अच्छे होते हैं। मैंने यह कड़ी मेहनत सीखी है। –

+0

आप एक्सएमएल में बस सबकुछ बदल नहीं सकते हैं जो सत्य के साथ सच है और झूठी झूठी है। यह निश्चित रूप से बेवकूफ है और निश्चित रूप से कुछ प्रकार के प्रतिक्रियाओं को तोड़ने जा रहा है। क्या होगा यदि वहां कुछ संग्रहीत किया गया था जो केस संवेदनशील था और इसमें शब्द सच था? अचानक यह काम नहीं करता है ... –

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