Пример #1
0
func main() {
	// let's create a message stream
	buf := new(bytes.Buffer)
	// load a couple of messages into it
	_, _ = buf.Write(msg1)
	_, _ = buf.Write(msg2)

	n := 0
	for {
		n++
		// read the stream as Map values - quit on io.EOF
		m, raw, merr := mxj.NewMapXmlReaderRaw(buf)
		if merr != nil && merr != io.EOF {
			// handle error - for demo we just print it and continue
			fmt.Printf("msg: %d - merr: %s\n", n, merr.Error())
			continue
		} else if merr == io.EOF {
			break
		}

		// the first keypair retains values if data correct
		// the second keypair relabels "idnet" to "netid"
		n, _ := m.NewMap("data.netid", "data.idnet:data.netid")
		x, _ := n.XmlIndent("", "  ")

		fmt.Println("original value:", string(*raw))
		fmt.Println("new value:")
		fmt.Println(string(x))
	}
}
Пример #2
0
func main() {
	// let's create a message stream
	buf := new(bytes.Buffer)
	// load a couple of messages into it
	_, _ = buf.Write(msg1)
	_, _ = buf.Write(msg2)

	n := 0
	for {
		n++
		// read the stream as Map values - quit on io.EOF
		m, raw, merr := mxj.NewMapXmlReaderRaw(buf)
		if merr != nil && merr != io.EOF {
			// handle error - for demo we just print it and continue
			fmt.Printf("msg: %d - merr: %s\n", n, merr.Error())
			continue
		} else if merr == io.EOF {
			break
		}
		fmt.Println("\nMessage to parse:", string(raw))
		fmt.Println("Map value for XML message:", m.StringIndent())

		// get the values for "netid" or "idnet" key using path == "data.*"
		values, _ := m.ValuesForPath("data.*")
		fmt.Println("\nmsg:", n, "> path == data.* - got array of values, len:", len(values))
		for i, val := range values {
			fmt.Println("ValuesForPath result array member -", i, ":", val)
			fmt.Println("              k:v pairs for array member:", i)
			for key, val := range val.(map[string]interface{}) {
				// You'd probably want to process the value, as appropriate.
				// Here we just print it out.
				fmt.Println("\t\t", key, ":", val)
			}
		}

		// This shows what happens if you wildcard the value keys for "idnet" and "netid"
		values, _ = m.ValuesForPath("data.*.*")
		fmt.Println("\npath == data.*.* - got an array of values, len(v):", len(values))
		fmt.Println("(Note: values returned by ValuesForPath are at maximum depth of the tree. So just have values.)")
		for i, val := range values {
			fmt.Println("ValuesForPath array member -", i, ":", val)
		}
	}
}
Пример #3
0
func main() {
	var file string
	flag.StringVar(&file, "file", "", "file to process")
	flag.Parse()

	fh, fherr := os.Open(file)
	if fherr != nil {
		fmt.Println("fherr:", fherr.Error())
		return
	}
	defer fh.Close()
	fmt.Println(time.Now().String(), "... File Opened:", file)

	/*
		// Get the XML data set from the file.
		fs, _ := fh.Stat()
		xmldata := make([]byte, fs.Size())
		n, frerr := fh.Read(xmldata)
		if frerr != nil {
			fmt.Println("frerr:", frerr.Error())
			return
		}
		if int64(n) != fs.Size() {
			fmt.Println("n:", n, "fs.Size():", fs.Size())
			return
		}
		fmt.Println(time.Now().String(), "... File Read - size:", fs.Size())

		// load XML into a Map value
		m, merr := mxj.NewMapXml(xmldata)
	*/
	// Consume the file using os.File Reader.
	// Note: there is a single record with root tag of "Metrics".
	// Also: this is MUCH slower than using buffer or not loading raw XML.
	m, raw, merr := mxj.NewMapXmlReaderRaw(fh)
	if merr != nil {
		log.Fatal("merr:", merr.Error())
	}
	fmt.Println(time.Now().String(), "... XML Unmarshaled - len:", len(m))
	fmt.Println("raw XML buffer size (should be same as File size):", len(raw))

	// Get just the key values of interest.
	// Could also use m.ValuesForKey("Metric"),
	// since there's just the one path.
	metricVals, err := m.ValuesForPath("Metrics.Metric")
	if err != nil {
		log.Fatal("err:", err.Error())
	}
	fmt.Println(time.Now().String(), "... ValuesFromKeyPath - len:", len(metricVals))

	// now just manipulate Map entries returned as []interface{} array.
	for _, v := range metricVals {
		aMetricVal := v.(map[string]interface{})

		// create file to hold csv data sets
		id := aMetricVal["-id"].(string)
		desc := aMetricVal["-description"].(string)
		mf, mferr := os.OpenFile(id+".csv", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666)
		if mferr != nil {
			fmt.Println("mferr:", mferr.Error())
			return
		}

		fmt.Print(time.Now().String(), " id: ", id, " desc: ", desc)
		mf.WriteString(id + "," + desc + "\n")

		// rescan looking for keys with data: Values or Value
		for key, val := range aMetricVal {
			switch key {
			case "Values":
				// extract the list of "Value" from map
				values := val.(map[string]interface{})["Value"].([]interface{})
				fmt.Println(" len(Values):", len(values))

				// first line in file is the metric label values (keys)
				var gotKeys bool
				for _, vval := range values {
					valueEntry := vval.(map[string]interface{})

					// no guarantee that range on map will follow any sequence
					lv := len(valueEntry)
					list := make([][2]string, lv)
					var i int
					for k, v := range valueEntry {
						list[i][0] = k
						list[i][1] = v.(string)
						i++
					}
					sort.Sort(mylist(list))

					// extract keys as column header on first pass
					if !gotKeys {
						// print out the keys
						var gotFirstKey bool
						// for kk, _ := range valueEntry {
						for i := 0; i < lv; i++ {
							if gotFirstKey {
								mf.WriteString(",")
							} else {
								gotFirstKey = true
							}
							// strip prepended hyphen
							mf.WriteString((list[i][0])[1:])
						}
						mf.WriteString("\n")
						gotKeys = true
					}

					// print out values
					var gotFirstVal bool
					// for _, vv := range valueEntry {
					for i := 0; i < lv; i++ {
						if gotFirstVal {
							mf.WriteString(",")
						} else {
							gotFirstVal = true
						}
						mf.WriteString(list[i][1])
					}

					// terminate row of data
					mf.WriteString("\n")
				}
			case "Value":
				vv := val.(map[string]interface{})
				fmt.Println(" len(Value):", len(vv))
				mf.WriteString("value\n" + vv["-value"].(string) + "\n")
			}
		}
		mf.Close()
	}
}