2012-10-24 13 views
6

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

फ़ाइल:

पाठ, SomeDouble, MoreText

"अच्छा", 1.23, "अच्छी"

"बुरा", "बैड"

मैं अगर

public class Test 
{ 
    [CsvField(Name = "Text")] 
    public string Text { get; set; } 

    [CsvField(Name = "SomeDouble")] 
    public double? SomeDouble{ get; set; } 

    [CsvField(Name = "MoreText")] 
    public string MoreText{ get; set; } 
} 
में इसे आजमाएं और मानचित्र करें

तो मैं इस तरह एक त्रुटि प्राप्त:

CsvHelper.CsvReaderException: '2' (1-आधारित)

फील्ड: एक त्रुटि प्रकार

पंक्ति के एक रिकॉर्ड को पढ़ने का प्रयास हुआ सूचकांक: '1' (0-आधारित)

फ़ील्ड का नाम: 'SomeDouble'

फ़ील्ड मान: ''

सिस्टम। अपवाद: डबल के लिए मान्य मान नहीं है। ---> सिस्टम। फ़ॉर्मेट अपवाद: इनपुट स्ट्रिंग सही प्रारूप में नहीं थी।
System.Number.ParseDouble पर (स्ट्रिंग मान, NumberStyles विकल्प, NumberFormatInfo numfmt) System.ComponentModel.DoubleConverter.FromString (स्ट्रिंग मान, NumberFormatInfo formatInfo) पर System.ComponentModel.BaseNumberConverter.ConvertFrom (ITypeDescriptorContext संदर्भ में, संस्कृति, वस्तु मूल्य) --- System.ComponentModel.NullableConverter.ConvertFrom पर भीतरी अपवाद स्टैक ट्रेस की समाप्ति --- System.ComponentModel.BaseNumberConverter.ConvertFrom (ITypeDescriptorContext संदर्भ, CultureInfo संस्कृति, वस्तु मूल्य) पर (ITypeDescriptorContext CultureInfo संदर्भ, संस्कृतिइन्फो संस्कृति, वस्तु मूल्य)परlambda_method (बंद, ICsvReader) CsvHelper.CsvReader.d__0`1.MoveNext()

मैं इसे देखना के रूप में, मेरे विकल्प एक कस्टम पार्सर बनाने के लिए, या एक स्ट्रिंग संपत्ति में अपने मूल्य मैप करने के लिए कर रहे हैं और कर में वहाँ पार्सिंग।

क्या कोई अन्य विकल्प हैं?

यह अच्छा होगा अगर मैं कॉन्फ़िगर कर सकूं कि मैं सफेद जगह को शून्य के रूप में देखना चाहता हूं।

अनुरोध अनुसार, यहाँ एक कोड नमूना है कि समस्या reproduces

static class Program 
    { 
     public class Test 
     { 
      [CsvField(Name = "Text")] 
      public string Text { get; set; } 

      [CsvField(Name = "SomeDouble")] 
      public double? SomeDouble { get; set; } 

      [CsvField(Name = "MoreText")] 
      public string MoreText { get; set; } 
     } 

     static void Main(string[] args) 
     { 
      // create fake in memory file 
      var memoryStream = new MemoryStream(); 
      var streamWriter = new StreamWriter(memoryStream); 
      streamWriter.WriteLine("Text,SomeDouble,MoreText"); 
      streamWriter.WriteLine("Good, 1.23, Good"); 
      streamWriter.WriteLine("Bad, ,Bad"); 

      streamWriter.Flush(); 

      //reset the file to the begining 
      memoryStream.Position = 0; 

      using (
       var csv = 
        new CsvReader(
         new StreamReader(memoryStream))) 
      { 
       // this call will blow up with the exception. 
       var records = csv.GetRecords<Test>().ToList(); 

       //carry on and do stuff with 'records'... 
      } 
    } 

धन्यवाद है।

+0

क्या आप सी पोस्ट कर सकते हैं वास्तव में असफल होने वाली विधि के लिए ode, मैं CSVHelper से परिचित नहीं हूं। –

+0

मैंने प्रश्न को बेहतर उदाहरण – RMK

+0

के साथ संपादित किया है, मुझे लगता है कि यह पैकेज नहीं करता है, लेकिन यह मदद करता है: [कस्टम टाइपकॉन्टर] (https://github.com/JoshClose/CsvHelper/wiki/कस्टम-टाइप कनवर्टर) मैं यह देखने जा रहा हूं कि मुझे इसके साथ कहीं भी मिलता है, मैं भी उस सुविधा का उपयोग कर सकता हूं। अगर आपको समाधान मिल जाए तो कृपया पोस्ट करें। –

उत्तर

6

अंत में मैं अपना खुद का प्रकार कनवर्टर बनाने के साथ चला गया जो व्हाइटस्पेस को एक शून्य के रूप में पेश करेगा।

Map(x => x.SomeDouble) 
    .ConvertUsing(row => 
     string.IsNullOrWhiteSpace(row.GetField("SomeDouble")) ? 
      (double?) null : 
      Convert.ToDouble(row.GetField("SomeDouble"))); 

मैं थोड़ा सहायक कार्य करता है और कॉल करना चाहते हैं:

public class WhiteSpaceToNullableTypeConverter<T> : TypeConverter where T : struct 
{ 
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
    { 
     return sourceType == typeof (string); 
    } 

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) 
    { 
     return destinationType == typeof (T?); 
    } 

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, 
             object value) 
    { 
     T? result = null; 

     var stringValue = (string) value; 
     if (!string.IsNullOrWhiteSpace(stringValue)) 
     { 
      var converter = TypeDescriptor.GetConverter(typeof(T)); 
      result = (T)converter.ConvertFrom(stringValue.Trim()); 
     } 

     return result; 
    } 

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, 
            object value, Type destinationType) 
    { 
     var result = (T?) value; 
     return result.ToString(); 
    } 
} 

इस

public class Test 
{ 
    [CsvField(Name = "Text")] 
    public string Text { get; set; } 

    [CsvField(Name = "SomeDouble")] 
    [TypeConverter(typeof(WhiteSpaceToNullableTypeConverter<Double>))] 
    public double? SomeDouble{ get; set; } 

    [CsvField(Name = "MoreText")] 
    public string MoreText{ get; set; } 
} 
3

एक आसान तरीका अपने ClassMap में ConvertUsing() का उपयोग करने के लिए है की तरह अपने मॉडल के लिए लागू करें उन्हें

Map(x => x.SomeDouble) 
    .ConvertUsing(row => GetOddballDouble(row.GetField("SomeDouble"))); 
संबंधित मुद्दे

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