1 回答

TA貢獻2016條經(jīng)驗 獲得超9個贊
文件是否在應(yīng)用程序之外發(fā)生更改?如果沒有,那么您可以在循環(huán)之前解析一次文件,維護坐標列表,并在每次更改時將其寫出,以便外部應(yīng)用程序可以看到中間結(jié)果。如果您計劃執(zhí)行更多轉(zhuǎn)換,或者想要在開始時從頭開始生成整個文件,這也將非常有用。
首先,您需要一個具有適當(dāng)標記的結(jié)構(gòu)(請參見 xml.Unmarshal)。我通常從在線生成器開始進行此類操作:
// type definition adapted from https://www.onlinetool.io/xmltogo/
type KML struct {
XMLName xml.Name `xml:"kml"`
Text string `xml:",chardata"`
XMLNS string `xml:"xmlns,attr"`
GX string `xml:"gx,attr"`
KML string `xml:"kml,attr"`
Atom string `xml:"atom,attr"`
Folder struct {
Text string `xml:",chardata"`
Name string `xml:"name"`
Open string `xml:"open"`
Document struct {
Text string `xml:",chardata"`
Name string `xml:"name"`
Placemark struct {
Text string `xml:",chardata"`
Style struct {
Text string `xml:",chardata"`
LineStyle struct {
Text string `xml:",chardata"`
Color string `xml:"color"`
Width string `xml:"width"`
} `xml:"LineStyle"`
PolyStyle struct {
Text string `xml:",chardata"`
Color string `xml:"color"`
Fill string `xml:"fill"`
Outline string `xml:"outline"`
} `xml:"PolyStyle"`
} `xml:"Style"`
LineString struct {
Text string `xml:",chardata"`
Tessellate string `xml:"tessellate"`
Coordinates string `xml:"coordinates"`
} `xml:"LineString"`
} `xml:"Placemark"`
} `xml:"Document"`
} `xml:"Folder"`
}
我會為此做一些幫助:
func readKML(filename string) (*KML, error) {
f, err := os.Open(filename)
if err != nil {
return nil, fmt.Errorf("opening KML file: %w", err) // contains filename
}
defer f.Close() // reading, ignoring error is acceptable
var kml KML
if err := xml.NewDecoder(f).Decode(&kml); err != nil {
return nil, fmt.Errorf("decoding XML from %q as KML: %w", filename, err)
}
return &kml, nil
}
func writeKML(filename string, kml *KML) error {
f, err := os.Create(filename)
if err != nil {
return fmt.Errorf("creating KML file: %w", err) // contains filename
}
defer f.Close() // double close is OK for *os.File
enc := xml.NewEncoder(f)
enc.Indent("", " ")
if err := enc.Encode(kml); err != nil {
return nil, fmt.Errorf("encoding KML to %q: %w", filename, err)
}
return nil
}
然后你的循環(huán)可以看起來像這樣:
kml, err := readKML(filename)
if err != nil {
return err // contains context
}
coordinates := strings.Fields(kml.Folder.Document.Placemark.LineString.Coordinates)
for coord := range incoming {
line := fmt.Sprintf("%f,%f,%d\n", coord.Lat, coord.Long, 0)
coordinates = append(coordinates, coord)
kml.Folder.Document.Placemark.LineString.Coordinates = strings.Join(coordinates, "\n")
if err := writeKML(filename, kml); err != nil {
log.Printf("Warning: failed to update %q: %s", filename, err)
}
}
在查看您擁有的代碼時,我懷疑問題在于您正在延遲文件關(guān)閉,這將在函數(shù)返回時執(zhí)行,而不是在循環(huán)繼續(xù)時執(zhí)行。您也可以使此方法正常工作,為此,我建議將邏輯分解為函數(shù),以便可以獨立測試每個部分,這也可能意味著您的延遲現(xiàn)在已在函數(shù)中正確限定。
- 1 回答
- 0 關(guān)注
- 124 瀏覽
添加回答
舉報