Example #1
0
func TestMobileSitemaps(t *testing.T) {
	doc := etree.NewDocument()
	root := doc.CreateElement("root")

	data := URL{"loc": "/mobile", "mobile": true}

	expect := []byte(`
	<root>
	  <loc>/mobile</loc>
	  <mobile:mobile/>
	</root>`)

	SetBuilderElementValue(root, data.URLJoinBy("loc", "host", "loc"), "loc")
	SetBuilderElementValue(root, data, "mobile")

	buf := &bytes.Buffer{}
	doc.WriteTo(buf)

	mdata, _ := mxj.NewMapXml(buf.Bytes())
	mexpect, _ := mxj.NewMapXml(expect)

	if !reflect.DeepEqual(mdata, mexpect) {
		t.Error(`Failed to generate sitemap xml thats deferrent output value in URL type`)
	}
}
func TestImageSitemaps(t *testing.T) {
	doc := etree.NewDocument()
	root := doc.CreateElement("root")

	data := URL{"loc": "/images", "image": []URL{
		{"loc": "http://www.example.com/image.png", "title": "Image"},
		{"loc": "http://www.example.com/image1.png", "title": "Image1"},
	}}
	expect := []byte(`
	<root>
		<image:image>
			<image:loc>http://www.example.com/image.png</image:loc>
			<image:title>Image</image:title>
		</image:image>
		<image:image>
			<image:loc>http://www.example.com/image1.png</image:loc>
			<image:title>Image1</image:title>
		</image:image>
	</root>`)

	SetBuilderElementValue(root, data, "image")
	buf := &bytes.Buffer{}
	doc.WriteTo(buf)

	mdata, _ := mxj.NewMapXml(buf.Bytes())
	mexpect, _ := mxj.NewMapXml(expect)

	if !reflect.DeepEqual(mdata, mexpect) {
		t.Error(`Failed to generate sitemap xml thats deferrent output value in URL type`)
	}
}
// IsCompatible compares two XML strings and returns true if the second has all the same element names and value types as the first.
// The elements don't have to be in the same order.
// The second XML string can have additional elements not present in the first.
func IsCompatible(a, b string) (compatible bool, err error) {
	aMap, err := mxj.NewMapXml([]byte(a), true)
	if err != nil {
		return
	}
	bMap, err := mxj.NewMapXml([]byte(b), true)
	if err != nil {
		return
	}
	return isStructurallyTheSame(aMap, bMap)
}
Example #4
0
// Emulator returns appropriate path to QEMU emulator for a given architecture
func (d *Driver) Emulator(arch string) (string, error) {
	switch arch {
	case "x86_64":
	case "i686":
	default:
		return "", utils.FormatError(fmt.Errorf("Unsupported architecture(%s).Only i686 and x86_64 supported", arch))
	}

	out, err := d.Run("virsh capabilities")
	if err != nil {
		return "", utils.FormatError(err)
	}

	m, err := mxj.NewMapXml([]byte(out))
	if err != nil {
		return "", utils.FormatError(err)
	}

	v, _ := m.ValuesForPath("capabilities.guest.arch", "-name:"+arch)
	// fixing https://github.com/dorzheh/deployer/issues/2
	if len(v) == 0 {
		return "", utils.FormatError(fmt.Errorf("Can't gather a KVM guest information for architecture %s.", arch))
	}
	return v[0].(map[string]interface{})["emulator"].(string), nil

}
func confAmq(
	amqConfPath string,
	confPolicyEntry string,
	confLevelDB string) string {

	xmlStr := gd.StrFromFilePath(amqConfPath)
	xmlMap, _ := mxj.NewMapXml([]byte(xmlStr))

	step := Step{&xmlMap}

	// flow
	(&step).
		SetJvmHeap("80").
		RemoveLogQuery().
		InsertPolicyEntry(confPolicyEntry).
		RemoveKahadb().
		AddLevelDB(confLevelDB).
		FixAmpersand().
		FixColonKey()
	// dd(xmlMap)

	resultBytes, _ := mxj.AnyXmlIndent(
		xmlMap["beans"], "", "  ", "beans")
	r := gd.BytesToString(resultBytes)

	return r
}
Example #6
0
func main() {
	m, err := mxj.NewMapXml(data)
	if err != nil {
		fmt.Println("err:", err)
	}
	fmt.Println(m.StringIndentNoTypeInfo())

	doc, err := m.XmlIndent("", "  ")
	if err != nil {
		fmt.Println("err:", err)
	}
	fmt.Println(string(doc))

	val, err := m.ValuesForKey("child1")
	if err != nil {
		fmt.Println("err:", err)
	}
	fmt.Println("val:", val)

	mxj.XmlGoEmptyElemSyntax()
	doc, err = mxj.AnyXmlIndent(val, "", "  ", "child1")
	if err != nil {
		fmt.Println("err:", err)
	}
	fmt.Println(string(doc))
}
Example #7
0
func main() {
	// parse XML into a Map
	m, merr := mxj.NewMapXml(xmlData)
	if merr != nil {
		fmt.Println("merr:", merr.Error())
		return
	}

	// extract the 'list3-1-1-1' node - there'll be just 1?
	// NOTE: attribute keys are prepended with '-'
	lstVal, lerr := m.ValuesForPath("*.*.*.*.*", "-name:list3-1-1-1")
	if lerr != nil {
		fmt.Println("ierr:", lerr.Error())
		return
	}

	// assuming just one value returned - create a new Map
	mv := mxj.Map(lstVal[0].(map[string]interface{}))

	// extract the 'int' values by 'name' attribute: "-name"
	// interate over list of 'name' values of interest
	var names = []string{"field1", "field2", "field3", "field4", "field5"}
	for _, n := range names {
		vals, verr := mv.ValuesForKey("int", "-name:"+n)
		if verr != nil {
			fmt.Println("verr:", verr.Error(), len(vals))
			return
		}

		// values for simple elements have key '#text'
		// NOTE: there can be only one value for key '#text'
		fmt.Println(n, ":", vals[0].(map[string]interface{})["#text"])
	}
}
Example #8
0
func collect(w http.ResponseWriter, r *http.Request) {
	username, password, ok := r.BasicAuth()
	if ok {
		_ = fmt.Sprintf("Username: %s | Password: %s", username, password)
		body, err := ioutil.ReadAll(r.Body)
		if err != nil {
			log.Fatal(err)
		}
		mxj.XmlCharsetReader = charset.NewReader
		m, err := mxj.NewMapXml(body) // unmarshal
		if err != nil {
			log.Fatal(err)
		}
		// Single path
		path := m.PathForKeyShortest("avg01")
		val, err := m.ValueForPath(path)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(val)
		// Multi-path
		paths := m.PathsForKey("percent")
		for _, path := range paths {
			val, err := m.ValueForPath(path)
			if err != nil {
				log.Fatal(err)
			}
			fmt.Println(val)
		}
		io.WriteString(w, "Success")
	}
}
func getParsedMap(xmlData []byte) {
	m, err := mxj.NewMapXml(xmlData)
	if err != nil {
		panic("error mapping file")
	}
	xmlMap = m
}
Example #10
0
func (tree *XMLHandler) Decode() (err error) {
	if len(tree.Content) == 0 {
		err = fmt.Errorf("XMLHandler.FileContent is empty!")
		return
	}
	//err = xml.Unmarshal(tree.FileContent, &tree.Value)
	tree.Value, err = mxj.NewMapXml(tree.Content, true)
	return
}
func TestAttrWithoutTypedef(t *testing.T) {
	doc := etree.NewDocument()
	root := doc.CreateElement("root")

	data := URL{"loc": "/videos", "video": URL{
		"thumbnail_loc": "http://www.example.com/video1_thumbnail.png",
		"title":         "Title",
		"description":   "Description",
		"content_loc":   "http://www.example.com/cool_video.mpg",
		"category":      "Category",
		"tag":           []string{"one", "two", "three"},
		"player_loc":    Attrs{"https://f.vimeocdn.com/p/flash/moogaloop/6.2.9/moogaloop.swf?clip_id=26", map[string]string{"allow_embed": "Yes", "autoplay": "autoplay=1"}},
	}}

	expect := []byte(`
	<root>
		<video:video>
			<video:thumbnail_loc>http://www.example.com/video1_thumbnail.png</video:thumbnail_loc>
			<video:title>Title</video:title>
			<video:description>Description</video:description>
			<video:content_loc>http://www.example.com/cool_video.mpg</video:content_loc>
			<video:tag>one</video:tag>
			<video:tag>two</video:tag>
			<video:tag>three</video:tag>
			<video:category>Category</video:category>
			<video:player_loc allow_embed="Yes" autoplay="autoplay=1">https://f.vimeocdn.com/p/flash/moogaloop/6.2.9/moogaloop.swf?clip_id=26</video:player_loc>
		</video:video>
	</root>`)

	SetBuilderElementValue(root, data, "video")

	buf := &bytes.Buffer{}
	// doc.Indent(2)
	doc.WriteTo(buf)

	mdata, _ := mxj.NewMapXml(buf.Bytes())
	mexpect, _ := mxj.NewMapXml(expect)

	// print(string(buf.Bytes()))

	if !reflect.DeepEqual(mdata, mexpect) {
		t.Error(`Failed to generate sitemap xml thats deferrent output value in URL type`)
	}
}
func TestNewsSitemaps(t *testing.T) {
	doc := etree.NewDocument()
	root := doc.CreateElement("root")

	data := URL{"loc": "/news", "news": URL{
		"publication": URL{
			"name":     "Example",
			"language": "en",
		},
		"title":            "My Article",
		"keywords":         "my article, articles about myself",
		"stock_tickers":    "SAO:PETR3",
		"publication_date": "2011-08-22",
		"access":           "Subscription",
		"genres":           "PressRelease",
	}}
	expect := []byte(`
	<root>
		<news:news>
			<news:keywords>my article, articles about myself</news:keywords>
			<news:stock_tickers>SAO:PETR3</news:stock_tickers>
			<news:publication_date>2011-08-22</news:publication_date>
			<news:access>Subscription</news:access>
			<news:genres>PressRelease</news:genres>
			<news:publication>
				<news:name>Example</news:name>
				<news:language>en</news:language>
			</news:publication>
			<news:title>My Article</news:title>
		</news:news>
	</root>`)

	SetBuilderElementValue(root, data, "news")
	buf := &bytes.Buffer{}
	doc.WriteTo(buf)

	mdata, _ := mxj.NewMapXml(buf.Bytes())
	mexpect, _ := mxj.NewMapXml(expect)

	if !reflect.DeepEqual(mdata, mexpect) {
		t.Error(`Failed to generate sitemap xml thats deferrent output value in URL type`)
	}
}
Example #13
0
File: xj2s.go Project: postfix/xj2s
func Xml2Struct(xdata []byte, Nesting bool) string {
	m, err := mxj.NewMapXml(xdata)
	if err != nil {
		panic(err)
	}
	paths := m.LeafPaths()
	if Nesting {
		return "Not implement yet..."
	} else {
		RootName, RootStruct, RestStructs := XmlPath2SrtructLinesNoNesting(paths)
		return RootDatas2Struct(RootName, RootStruct, RestStructs)
	}
}
func TestVideoSitemaps(t *testing.T) {
	doc := etree.NewDocument()
	root := doc.CreateElement("root")

	data := URL{"loc": "/videos", "video": URL{
		"thumbnail_loc": "http://www.example.com/video1_thumbnail.png",
		"title":         "Title",
		"description":   "Description",
		"content_loc":   "http://www.example.com/cool_video.mpg",
		"category":      "Category",
		"tag":           []string{"one", "two", "three"},
	}}

	expect := []byte(`
	<root>
		<video:video>
			<video:thumbnail_loc>http://www.example.com/video1_thumbnail.png</video:thumbnail_loc>
			<video:title>Title</video:title>
			<video:description>Description</video:description>
			<video:content_loc>http://www.example.com/cool_video.mpg</video:content_loc>
			<video:tag>one</video:tag>
			<video:tag>two</video:tag>
			<video:tag>three</video:tag>
			<video:category>Category</video:category>
		</video:video>
	</root>`)

	SetBuilderElementValue(root, data, "video")
	buf := &bytes.Buffer{}
	doc.WriteTo(buf)

	mdata, _ := mxj.NewMapXml(buf.Bytes())
	mexpect, _ := mxj.NewMapXml(expect)

	if !reflect.DeepEqual(mdata, mexpect) {
		t.Error(`Failed to generate sitemap xml thats deferrent output value in URL type`)
	}
}
func (rt ResponseTransformMiddleware) HandleResponse(rw http.ResponseWriter, res *http.Response, req *http.Request, ses *SessionState) error {
	_, versionPaths, _, _ := rt.Spec.GetVersionData(req)
	found, meta := rt.Spec.CheckSpecMatchesStatus(req.URL.Path, req.Method, versionPaths, TransformedResponse)
	if found {
		thisMeta := meta.(*TransformSpec)

		// Read the body:
		defer res.Body.Close()
		body, err := ioutil.ReadAll(res.Body)

		// Put into an interface:
		var bodyData interface{}
		switch thisMeta.TemplateMeta.TemplateData.Input {
		case tykcommon.RequestXML:
			mxj.XmlCharsetReader = WrappedCharsetReader
			bodyData, err = mxj.NewMapXml(body) // unmarshal
			if err != nil {
				log.WithFields(logrus.Fields{
					"prefix":      "outbound-transform",
					"server_name": rt.Spec.APIDefinition.Proxy.TargetURL,
					"api_id":      rt.Spec.APIDefinition.APIID,
					"path":        req.URL.Path,
				}).Error("Error unmarshalling XML: ", err)
			}
		case tykcommon.RequestJSON:
			json.Unmarshal(body, &bodyData)
		default:
			json.Unmarshal(body, &bodyData)
		}

		// Apply to template
		var bodyBuffer bytes.Buffer
		err = thisMeta.Template.Execute(&bodyBuffer, bodyData)

		if err != nil {
			log.WithFields(logrus.Fields{
				"prefix":      "outbound-transform",
				"server_name": rt.Spec.APIDefinition.Proxy.TargetURL,
				"api_id":      rt.Spec.APIDefinition.APIID,
				"path":        req.URL.Path,
			}).Error("Failed to apply template to request: ", err)
		}

		res.ContentLength = int64(bodyBuffer.Len())
		res.Header.Set("Content-Length", strconv.Itoa(bodyBuffer.Len()))
		res.Body = ioutil.NopCloser(&bodyBuffer)
	}

	return nil
}
Example #16
0
func main() {
	// mxj.CoerceKeysToLower(true)
	// mxj.IncludeTagSeqNum(true)
	mxj.SetAttrPrefix("@")
	m, err := mxj.NewMapXml(xmldata, true)
	if err != nil {
		log.Fatal("err:", err.Error())
	}

	// js, _ := m.Json()
	js, _ := m.JsonIndent("", "    ")
	log.Println(string(js))

	// Output:
	// {
	//     "books": {
	//         "book": [
	//             {
	//                 "#text": "book1",
	//                 "@Order": 1,
	//                 "Author": "William H. Gaddis",
	//                 "Review": "One of the great seminal American novels of the 20th century.",
	//                 "Title": "The Recognitions"
	//             },
	//             {
	//                 "#text": "book2",
	//                 "@Order": 2,
	//                 "Author": "Austin Tappan Wright",
	//                 "Review": "An example of earlier 20th century American utopian fiction.",
	//                 "Title": "Islandia"
	//             },
	//             {
	//                 "#text": "book3",
	//                 "@Order": 3,
	//                 "Author": "John Hawkes",
	//                 "Review": "A lyrical novel about the construction of Ft. Peck Dam in Montana.",
	//                 "Title": "The Beetle Leg"
	//             },
	//             {
	//                 "#text": "book3",
	//                 "@Order": 4,
	//                 "Author": "T.E. Porter",
	//                 "Review": "A magical novella.",
	//                 "Title": "King's Day"
	//             }
	//         ]
	//     }
	// }
}
func (step *Step) AddLevelDB(confLevelDB string) *Step {
	xmlMap := step.Value

	prf("read LevelDBconfPath %s...\n", confLevelDB)
	nxmlStr := gd.StrFromFilePath(confLevelDB)
	nxmlMap, _ := mxj.NewMapXml([]byte(nxmlStr))

	m := make(map[string]interface{})
	m["replicatedLevelDB"] = nxmlMap["replicatedLevelDB"]

	paPath := xmlMap.PathForKeyShortest("persistenceAdapter")
	xmlMap.SetValueForPath(m, paPath)

	return step
}
Example #18
0
func TestGeoSitemaps(t *testing.T) {
	doc := etree.NewDocument()
	root := doc.CreateElement("root")

	data := URL{"loc": "/geos", "geo": URL{"format": "kml"}}

	expect := []byte(`
	<root>
		<geo:geo>
			<geo:format>kml</geo:format>
		</geo:geo>
	</root>`)

	SetBuilderElementValue(root, data, "geo")
	buf := &bytes.Buffer{}
	doc.WriteTo(buf)

	mdata, _ := mxj.NewMapXml(buf.Bytes())
	mexpect, _ := mxj.NewMapXml(expect)

	if !reflect.DeepEqual(mdata, mexpect) {
		t.Error(`Failed to generate sitemap xml thats deferrent output value in URL type`)
	}
}
func (step *Step) InsertPolicyEntry(confPolicyEntry string) *Step {
	xmlMap := step.Value

	prf("read PolicyEntryPath %s...\n", confPolicyEntry)
	nxmlStr := gd.StrFromFilePath(confPolicyEntry)
	nxmlMap, _ := mxj.NewMapXml([]byte(nxmlStr))

	pePath := xmlMap.PathForKeyShortest("policyEntry")
	peValues, _ := xmlMap.ValuesForPath(pePath)
	peValues = append(peValues, nxmlMap["policyEntry"])

	xmlMap.SetValueForPath(peValues, pePath)

	return step
}
func confJetty(jettyConfPath string, portValue string) string {
	xmlStr := gd.StrFromFilePath(jettyConfPath)
	// pln(xmlStr)
	xmlMap, _ := mxj.NewMapXml([]byte(xmlStr))
	// dd(xmlMap)
	// pln(typeof(xmlMap))

	step := Step{&xmlMap}
	(&step).
		SetJettyPort(portValue).
		FixColonKey()
	// dd(xmlMap)

	resultBytes, _ := mxj.AnyXmlIndent(xmlMap["beans"], "", "  ", "beans")
	r := gd.BytesToString(resultBytes)
	return r
}
Example #21
0
func main() {
	fmt.Println("xmldata:", string(xmldata))

	m, merr := mxj.NewMapXml(xmldata)
	if merr != nil {
		fmt.Println("merr:", merr)
		return
	}

	// Attributes are keys with prepended hyphen, '-'.
	values, err := m.ValuesForPath("doc.some_tag.geoInfo.country.-name")
	if err != nil {
		fmt.Println("err:", err.Error())
	}

	for _, v := range values {
		fmt.Println("v:", v)
	}
}
Example #22
0
// SearchTorrentsFor is now commented
func SearchTorrentsFor(searchString string, torrents map[int][]string) map[int][]string {
	domain := "https://kat.cr/"
	suffix := "/?rss=1&field=seeders&sorder=desc"
	url := domain + "new" + suffix

	if searchString != "" {
		url = domain + "usearch/" + searchString + suffix
	}

	resp, err := http.Get(url)
	if err != nil {
		log.Print(err)
	}
	defer resp.Body.Close()
	xml, err := ioutil.ReadAll(resp.Body)
	m, err := mxj.NewMapXml(xml)
	m, _ = m["rss"].(map[string]interface{})
	m, _ = m["channel"].(map[string]interface{})
	if m["item"] != nil {
		items := m["item"].([]interface{})

		for key, value := range items {
			val, _ := value.(map[string]interface{})
			if val["verified"] == "0" || val["seeds"] == "0" {
				continue
			}

			title, _ := val["title"].(string)
			seeds, _ := val["seeds"].(string)
			magnetURIRaw, _ := val["magnetURI"].(string)

			torrents[key] = []string{title, seeds, magnetURIRaw}
		}

		return torrents
	}

	log.Printf("Torrent site '%s' response empty", domain)
	torrents[0] = []string{"Error connecting to " + domain, "N/A", ""}
	return torrents
}
Example #23
0
func partPath6(msg []byte) {
	fmt.Println("\nmsg:", string(msg))
	m, _ := mxj.NewMapXml(msg)
	fmt.Println("m:", m.StringIndent())
	path := "*.*.*.*.*.*.*"
	values, err := m.ValuesForPath(path)
	if err != nil {
		fmt.Println("err:", err.Error())
		return
	}
	if values == nil {
		fmt.Println("path:", path)
		fmt.Println("No ClaimStatusCodesResult code records.")
		return
	}
	fmt.Println("\nPath:", path)
	fmt.Println("Number of code records:", len(values))
	for n, v := range values {
		fmt.Printf("\t#%d: %v\n", n, v)
	}
}
Example #24
0
func main() {
	fmt.Println("xmldata:", string(xmldata))

	// get all image tag values - []interface{}
	m, merr := mxj.NewMapXml(xmldata)
	if merr != nil {
		fmt.Println("merr:", merr.Error())
		return
	}

	// grab all values for attribute "src"
	// Note: attributes are prepended with a hyphen, '-'.
	sources, err := m.ValuesForKey("-src")
	if err != nil {
		fmt.Println("err:", err.Error())
		return
	}

	for _, src := range sources {
		fmt.Println(src)
	}
}
Example #25
0
func main() {
	fmt.Println(string(xmldata))

	m, err := mxj.NewMapXml(xmldata)
	if err != nil {
		log.Fatal("err:", err.Error())
	}

	v, _ := m.ValuesForKey("books")
	fmt.Println("path: books; len(v):", len(v))
	fmt.Printf("\t%+v\n", v)

	v, _ = m.ValuesForPath("books.book")
	fmt.Println("path: books.book; len(v):", len(v))
	for _, vv := range v {
		fmt.Printf("\t%+v\n", vv)
	}

	v, _ = m.ValuesForPath("books.*")
	fmt.Println("path: books.*; len(v):", len(v))
	for _, vv := range v {
		fmt.Printf("\t%+v\n", vv)
	}

	v, _ = m.ValuesForPath("books.*.title")
	fmt.Println("path: books.*.title len(v):", len(v))
	for _, vv := range v {
		fmt.Printf("\t%+v\n", vv)
	}

	v, _ = m.ValuesForPath("books.*.*")
	fmt.Println("path: books.*.*; len(v):", len(v))
	for _, vv := range v {
		fmt.Printf("\t%+v\n", vv)
	}
}
Example #26
0
func fullPath(xmldata [][]byte) {
	for i, msg := range xmldata {
		fmt.Println("\ndoc:", i)
		fmt.Println(string(msg))
		// decode the XML
		m, _ := mxj.NewMapXml(msg)

		// get the value for the key path of interest
		path := "Envelope.Body.GetClaimStatusCodesResponse.GetClaimStatusCodesResult.ClaimStatusCodeRecord"
		values, err := m.ValuesForPath(path)
		if err != nil {
			fmt.Println("err:", err.Error())
			return
		}
		if values == nil {
			fmt.Println("path:", path)
			fmt.Println("No ClaimStatusCodesResult code records.")
			continue
		}
		fmt.Println("\nPath:", path)
		fmt.Println("Number of code records:", len(values))
		fmt.Println("values:", values, "\n")
		for _, v := range values {
			switch v.(type) {
			case map[string]interface{}:
				fmt.Println("map[string]interface{}:", v.(map[string]interface{}))
			case []map[string]interface{}:
				fmt.Println("[]map[string]interface{}:", v.([]map[string]interface{}))
			case []interface{}:
				fmt.Println("[]interface{}:", v.([]interface{}))
			case interface{}:
				fmt.Println("interface{}:", v.(interface{}))
			}
		}
	}
}
Example #27
0
func main() {
	m, err := mxj.NewMapXml(data)
	if err != nil {
		fmt.Println("NewMapXml err:", err)
		return
	}
	// vals, err := m.ValuesForPath("author.first-name") // full-path option
	vals, err := m.ValuesForKey("first-name") // key-only alternatively
	if err != nil {
		fmt.Println("ValuesForPath err:", err)
		return
	} else if len(vals) == 0 {
		fmt.Println("no first-name vals")
		return
	}
	var fname, date string
	for _, v := range vals {
		vm, ok := v.(map[string]interface{})
		if !ok {
			fmt.Println("assertion failed")
			return
		}
		fn, ok := vm["#text"].(string)
		if !ok {
			fmt.Println("no #text tag")
			return
		}
		dt, ok := vm["-effect_range"].(string)
		if !ok {
			fmt.Println("no -effect_range attr")
			return
		}
		if dt > date {
			date = dt
			fname = fn
		}
	}
	/*
		// alternatively:
		//(however, this requires knowing what latest "effect_range" attribute value is)
		vals, err := m.ValuesForKey("first-name", "-effect_range:2012-")
		if len(vals) == 0 {
			fmt.Println("no #text vals")
			return
		}
		fname := vals[0].(map[string]interface{})["#text"].(string)
	*/

	// vals, err = m.ValuesForKey("last-name") // key-only option
	vals, err = m.ValuesForPath("author.last-name") // full-path option
	if err != nil {
		fmt.Println("ValuesForPath err:", err)
		return
	} else if len(vals) == 0 {
		fmt.Println("no last-name vals")
		return
	}
	lname := vals[0].(string)
	if err = m.SetValueForPath(fname+" "+lname, "author.full-name"); err != nil {
		fmt.Println("SetValueForPath err:", err)
		return
	}
	b, err := m.XmlIndent("", "  ")
	if err != nil {
		fmt.Println("XmlIndent err:", err)
		return
	}
	fmt.Println(string(b))
}
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
	// Note: there is a single record with root tag of "Metrics".
	m, merr := mxj.NewMapXml(xmldata)
	if merr != nil {
		log.Fatal("merr:", merr.Error())
	}
	fmt.Println(time.Now().String(), "... XML Unmarshaled - len:", len(m))

	// 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)
					type ev [2]string
					list := make([]ev, lv)
					var i int
					for k, v := range valueEntry {
						list[i][0] = k
						list[i][1] = v.(string)
						i++
					}

					// 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()
	}
}
			if err != nil {
				lua.Errorf(l, "%s", err.Error())
				panic("unreachable")
			}

			util.DeepPush(l, string(res))

			return 1
		},
	},

	{
		"decode",
		func(l *lua.State) int {
			res, err := mxj.NewMapXml([]byte(lua.CheckString(l, 1)))

			if err != nil {
				lua.Errorf(l, "%s", err.Error())
				panic("unreachable")
			}

			util.DeepPush(l, res)

			return 1
		},
	},
}

func openXMLLibrary(l *lua.State) {
	open := func(l *lua.State) int {
// ProcessRequest will run any checks on the request on the way through the system, return an error to have the chain fail
func (t *TransformMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Request, configuration interface{}) (error, int) {
	_, versionPaths, _, _ := t.TykMiddleware.Spec.GetVersionData(r)
	found, meta := t.TykMiddleware.Spec.CheckSpecMatchesStatus(r.URL.Path, r.Method, versionPaths, Transformed)
	if found {
		thisMeta := meta.(*TransformSpec)

		// Read the body:
		defer r.Body.Close()
		body, err := ioutil.ReadAll(r.Body)

		// Put into an interface:
		var bodyData interface{}
		switch thisMeta.TemplateMeta.TemplateData.Input {
		case tykcommon.RequestXML:
			mxj.XmlCharsetReader = WrappedCharsetReader
			var err error
			bodyData, err = mxj.NewMapXml(body) // unmarshal
			if err != nil {
				log.WithFields(logrus.Fields{
					"prefix":      "inbound-transform",
					"server_name": t.Spec.APIDefinition.Proxy.TargetURL,
					"api_id":      t.Spec.APIDefinition.APIID,
					"path":        r.URL.Path,
				}).Error("Error unmarshalling XML: ", err)
			}
		case tykcommon.RequestJSON:
			json.Unmarshal(body, &bodyData)
		default:
			// unset, assume an open field
			bodyData = make(map[string]interface{})
		}

		if thisMeta.TemplateMeta.TemplateData.EnableSession {
			ses := context.Get(r, SessionData).(SessionState)
			switch bodyData.(type) {
			case map[string]interface{}:
				bodyData.(map[string]interface{})["_tyk_meta"] = ses.MetaData
			}
		}

		if t.Spec.EnableContextVars {
			contextData := context.Get(r, ContextData)
			switch bodyData.(type) {
			case map[string]interface{}:
				bodyData.(map[string]interface{})["_tyk_context"] = contextData
			}
		}

		// Apply to template
		var bodyBuffer bytes.Buffer
		err = thisMeta.Template.Execute(&bodyBuffer, bodyData)
		if err != nil {
			log.WithFields(logrus.Fields{
				"prefix":      "inbound-transform",
				"server_name": t.Spec.APIDefinition.Proxy.TargetURL,
				"api_id":      t.Spec.APIDefinition.APIID,
				"path":        r.URL.Path,
			}).Error("Failed to apply template to request: ", err)
		}
		r.Body = ioutil.NopCloser(&bodyBuffer)
		r.ContentLength = int64(bodyBuffer.Len())
	}

	return nil, 200
}