2016-07-29 3 views
0

: - 예를 들어 문자열에 대한 모든 값이 동일한 유형했을 경우구문 분석을 plist XML

<key>KEY1</key><string>VALUE OF KEY1</string> 
<key>KEY2</key><string>VALUE OF KEY2</string> 
<key>KEY3</key><integer>42</integer> 
<key>KEY3</key><array> 
    <integer>1</integer> 
    <integer>2</integer> 
</array> 

구문 분석은 매우 간단하다. 하지만 내 경우에는 각 값이 문자열, 데이터, 정수, 부울, 배열 또는 dict 일 수 있습니다.

이 XML은 json과 거의 비슷하지만 형식이 고정되어 있으므로 변경할 수 없습니다. 그리고 나는 외부 패키지없이 솔루션을 선호합니다.

답변

1

encoding/xml에서 제공하는 하위 수준 구문 분석 인터페이스를 사용하면 XML 스트림의 개별 토큰 (예 : "시작 요소", "끝 요소"등)을 반복 할 수 있습니다.

encoding/xmlDecoder 유형의 Token() 방법을 참조하십시오.

0

데이터가 잘 구성되지 않았으므로 형식을 수정할 수 없기 때문에 xml.Unmarshal을 사용할 수 없으므로 새 디코더를 만든 다음 XML 요소를 처리 한 다음 토큰을 반복하여 사용합니다 DecodeElement를 하나씩 처리합니다. 아래 예제 코드에서는 모든 것을 맵에 넣습니다. 코드도 github here ...

package main 

import (
     "encoding/xml" 
    "strings" 
    "fmt" 
) 

type PlistArray struct { 
    Integer []int `xml:"integer"` 
} 

const in = "<key>KEY1</key><string>VALUE OF KEY1</string><key>KEY2</key><string>VALUE OF KEY2</string><key>KEY3</key><integer>42</integer><key>KEY3</key><array><integer>1</integer><integer>2</integer></array>" 

func main() { 
    result := map[string]interface{}{} 
    dec := xml.NewDecoder(strings.NewReader(in)) 
    dec.Strict = false 
    var workingKey string 

    for { 
     token, _ := dec.Token() 
     if token == nil { 
      break 
     } 
     switch start := token.(type) { 
     case xml.StartElement: 
      fmt.Printf("startElement = %+v\n", start) 
      switch start.Name.Local { 
      case "key": 
       var k string 
       err := dec.DecodeElement(&k, &start) 
       if err != nil { 
        fmt.Println(err.Error()) 
       } 
       workingKey = k 
      case "string": 
       var s string 
       err := dec.DecodeElement(&s, &start) 
       if err != nil { 
        fmt.Println(err.Error()) 
       } 
       result[workingKey] = s 
       workingKey = "" 
      case "integer": 
       var i int 
       err := dec.DecodeElement(&i, &start) 
       if err != nil { 
        fmt.Println(err.Error()) 
       } 
       result[workingKey] = i 
       workingKey = "" 
      case "array": 
       var ai PlistArray 
       err := dec.DecodeElement(&ai, &start) 
       if err != nil { 
        fmt.Println(err.Error()) 
       } 
       result[workingKey] = ai 
       workingKey = "" 
      default: 
       fmt.Errorf("Unrecognized token") 
      } 
     } 
    } 
    fmt.Printf("%+v", result) 

} 
+0

나는 또한 그 사이에 비슷한 것을 씁니다. https://github.com/lofcek/plist – lofcek

+0

위대한! 이 답변에 만족한다면 동의하십시오. – jxstanford

관련 문제