2014-12-16 4 views
2

데이터를 구문 분석하기 위해 데이터를 가져오고 데이터 유형 및 형식 (해당되는 경우)에 대한 필드 별 기준에 대한 지침을 제공하는 일반 파서가 있습니다. 예를 들어형식 및 형식 문자열을 사용하여 문자열을 개체로 변환

:

<Field Name="DateTime" Type="Pattern" Expression="\d{8} \d{2}\:\d{2}\:\d{2}" DataType="System.DateTime" Format="yyyyMMdd HH:mm:ss" /> 

유형이 날짜, 정수, 소수점, 값 유형이 될 수 있습니다. 형식은 날짜 또는 숫자 형식 일 수 있습니다.

Convert.ChangeType에는 사용자 지정 형식 문자열 만 사용하는 오버로드가 없습니다. IFormatProvider을 구현하려고했지만 그 작업을 수행하는 방법을 모르겠습니다.

그래서이 방법을 가능한 가장 일반적인 방법으로 작동시키는 방법을 찾으려고합니다.

Public Function ConvertValue(Value As String, Type As System.Type, Format As String) As Object 

    End Function 

날짜 데이터의 예는 "20141215 10:07:25" {String} 될 것이다, 그래서 당신은 하나 개의 크기에가는 모든 유형에 대한 모든 기능에 맞는대로 그냥만큼 ConvertValue("20141215 10:07:25", GetType(DateTime), "yyyyMMdd HH:mm:ss")

+0

질문의 시작 부분에있는 XML은 구문 분석 할 데이터가 아니라 구문 분석 규칙 정의의 일부인 것처럼 보입니다. 실제 데이터는 어떻게 보이고, 어떻게 'ConvertValue' 메소드에 공급 될까요? – stakx

+0

@stakx, 맞습니다. 나는 나의 질문을 편집했다. 감사! – toddmo

+0

여기서 '표현식'과 '유형'의 역할에 대해 이해하지 못합니까? –

답변

1

를 부를 것이다, 당신은 경우 것/사례 진술. 나는 일반적으로 직렬화 할 수없는 유형에 도움이 일반 컨버터를 가지고 있지만 토대없이 독립 함수로 변환하는 못 생기고 1을 만드는 :

Private Shared Function ConvertToT(Of T)(obj As String, fmt As String) As T 

    If GetType(T) Is GetType(DateTime) Then 

     Dim dt As DateTime 
     DateTime.TryParseExact(obj, fmt, CultureInfo.CurrentCulture, 
           DateTimeStyles.None, dt) 
     Return Convert.ChangeType(dt, GetType(T)) 

    ElseIf GetType(T) Is GetType(Decimal) Then 
     Dim dec As Decimal 
     If Decimal.TryParse(obj, dec) Then 
      Return Convert.ChangeType(dec, GetType(T)) 
     Else 
      Return Convert.ChangeType(Decimal.MinValue, GetType(T)) ' or exception 
     End If 

    ElseIf GetType(T) Is GetType(Double) Then 
     ' etc etc etc 

    End If 

End Function 

당신이 변환에 다른 기능을 사용할 필요가 있기 때문에, 긴 Case/If 블록을 가져옵니다. ConvertFromInvariantString과 같은 것을 사용하는 경우에도 반환 유형이 있습니다. 확장 세트 적은 cruft에가있는 것하고 조금 더 사용할 수있는 이러한 맥락에서 보인다

Module ParseExtensions 

    <Extension> 
    Public Function ParseToDate(dt As DateTime, data As String, 
        format As String) As DateTime 
     Dim newDate As DateTime 

     DateTime.TryParseExact(data, format, CultureInfo.CurrentCulture, 
           DateTimeStyles.None, newDate) 
     Return newDate 
    End Function 

    <Extension> 
    Public Function ParseToDecimal(dec As Decimal, 
          data As String) As Decimal 
     Dim newDec As Decimal 

     If Decimal.TryParse(data, newDec) Then 
      Return newDec 
     Else 
      Return Decimal.MinValue ' or exception 
     End If 
    End Function 

End Module 

사용 및 재판의 경우 :

enter image description here

1가 기능하지만, 추한.

+0

고마워요. 나는 컴파일 타임에'(Of Type) '을 가지지 않을 것이다. 그리고'Case' 문없이'ParseToDate'를 말할 수 없을 것입니다. 'Case' 주변에는 방법이 없다고 생각합니다. – toddmo

+0

오버로드 된 확장 메서드를 시도합니다 (모두 같은 이름이지만 diff 형식을 인수로 사용합니다). 그것이 트릭을하는지 봅니다. – toddmo

+0

나는'ParseFrom (string, format)'과 같은 좋은 접근 방식/이름을 좋아한다. XML 설명자를 생성하고 있습니까? 'ConvertToInvariantString'은 훌륭한 형식을 제공하며 어떠한 형식 기술자도 필요 없습니다. – Plutonix

1
Sub Test() 
    Dim dte As Date = CDate(ConvertValue("20141215 10:07:25", GetType(DateTime), "yyyyMMdd HH:mm:ss")) 
    MsgBox(dte.ToString) 
    Dim i As Integer = CInt(ConvertValue("1234", GetType(Integer), "0000")) 
    MsgBox(i.ToString) 
    End Sub 

    Public Function ConvertValue(Value As String, Type As System.Type, Format As String) As Object 
    If Type Is GetType(Date) Then 
     Dim dte As Date 
     Dim enAU As New Globalization.CultureInfo("en-AU") 
     If Not Date.TryParseExact(Value, Format, enAU, Globalization.DateTimeStyles.None, dte) Then 
     dte = New Date 
     End If 
     Return dte 
    ElseIf Type Is GetType(Integer) Then 
     Dim i As Integer 
     If Not Integer.TryParse(Value, i) Then 
     i = 0 
     End If 
     Return i 
    Else 
     Return Nothing 
    End If 
    End Function 
+0

좋은 "계획 B"입니다. 나는 그것을지지하지 않았다. 나는 현금화 할 수없는 해결책을 찾고있었습니다. 아마도 하나도 없을 것입니다. – toddmo

+0

감사합니다. 나는 또한 흥미가있을 것이다, 그러나 나는 형식 문자열 구문이 수십 년 동안 진화 해 왔으며 일반적인 해결책으로는 충분하지 않다고 생각한다. 잘만되면 나는 그것에 틀렸다! 행운을 빕니다 :-) – SSS

관련 문제