File: gonuts10seq.go

package info (click to toggle)
golang-github-clbanning-mxj 2.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,200 kB
  • sloc: xml: 176; makefile: 4
file content (106 lines) | stat: -rw-r--r-- 2,535 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* gonuts10.go - https://groups.google.com/forum/?fromgroups#!topic/golang-nuts/tf4aDQ1Hn_c
change:
<author>
    <first-name effect_range="1999-2011">Sam</first-name>
    <first-name effect_range="2012-">Kevin</first-name>
    <last-name>Smith</last-name>
   <full-name></full-name>
</author>

to:
<author>
     <first-name effect_range="1999-2011">Sam</first-name>
    <first-name effect_range="2012-">Kevin</first-name>
    <last-name>Smith</last-name>
   <full-name>Kevin Smith</full-name>
</author>

NOTE: use NewMapXmlSeq() and mv.XmlSeqIndent() to preserve structure.

Here we build the "full-name" element value from other values in the doc by selecting the
"first-name" value with the latest dates.
*/

package main

import (
	"fmt"
	"github.com/clbanning/mxj/v2"
	"strings"
)

var data = []byte(`
<author>
    <first-name effect_range="1999-2011">Sam</first-name>
    <first-name effect_range="2012-">Kevin</first-name>
    <last-name>Smith</last-name>
   <full-name></full-name>
</author>
`)

func main() {
	fmt.Println(string(data))
	m, err := mxj.NewMapXmlSeq(data)
	if err != nil {
		fmt.Println("NewMapXml err:", err)
		return
	}
	vals, err := m.ValuesForPath("author.first-name") // full-path option
	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
	var index int
	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
		}
		// extract the associated date
		dt, _ := mxj.Map(vm).ValueForPathString("#attr.effect_range.#text")
		if dt == "" {
			fmt.Println("no effect_range attr")
			return
		}
		dts := strings.Split(dt, "-")
		if len(dts) > 1 && dts[len(dts)-1] == "" {
			index = len(dts) - 2
		} else if len(dts) > 0 {
			index = len(dts) - 1
		}
		if len(dts) > 0 && dts[index] > date {
			date = dts[index]
			fname = fn
		}
	}

	vals, err = m.ValuesForPath("author.last-name.#text") // 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.#text"); err != nil {
		fmt.Println("SetValueForPath err:", err)
		return
	}
	b, err := m.XmlSeqIndent("", "  ")
	if err != nil {
		fmt.Println("XmlIndent err:", err)
		return
	}
	fmt.Println(string(b))
}