2016-07-29 10 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を1つずつ処理します。下の私のサンプルコードでは、すべてを地図に表示します。コードは、私はまた、その間中に似た何かを書く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