mirror of
https://github.com/cedricve/go-onvif.git
synced 2025-09-27 04:45:54 +08:00

Updated discoverDevices and createUserToken functions to handle errors properly. This includes the rare possibility createUserToken could send a new SOAP fault message if a uuid can not be generated (only in out-of-memory situations). Added vendoring to prevent future dependency issues. Side Note: Had vendoring not been added, the uuid dependency would cause problems if this go-onvif package was added to a project using vendoring. This is due to go defaulting to a last commit to the master branch, while vendoring defaults to the last published version. This quirk was obvious after seeing the uuid package pushed the breaking change to the master without also pushing it as a new version.
190 lines
3.9 KiB
Go
190 lines
3.9 KiB
Go
package mxj
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"reflect"
|
|
)
|
|
|
|
const (
|
|
DefaultElementTag = "element"
|
|
)
|
|
|
|
// Encode arbitrary value as XML.
|
|
//
|
|
// Note: unmarshaling the resultant
|
|
// XML may not return the original value, since tag labels may have been injected
|
|
// to create the XML representation of the value.
|
|
/*
|
|
Encode an arbitrary JSON object.
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/clbanning/mxj"
|
|
)
|
|
|
|
func main() {
|
|
jsondata := []byte(`[
|
|
{ "somekey":"somevalue" },
|
|
"string",
|
|
3.14159265,
|
|
true
|
|
]`)
|
|
var i interface{}
|
|
err := json.Unmarshal(jsondata, &i)
|
|
if err != nil {
|
|
// do something
|
|
}
|
|
x, err := mxj.AnyXmlIndent(i, "", " ", "mydoc")
|
|
if err != nil {
|
|
// do something else
|
|
}
|
|
fmt.Println(string(x))
|
|
}
|
|
|
|
output:
|
|
<mydoc>
|
|
<somekey>somevalue</somekey>
|
|
<element>string</element>
|
|
<element>3.14159265</element>
|
|
<element>true</element>
|
|
</mydoc>
|
|
*/
|
|
// Alternative values for DefaultRootTag and DefaultElementTag can be set as:
|
|
// AnyXml( v, myRootTag, myElementTag).
|
|
func AnyXml(v interface{}, tags ...string) ([]byte, error) {
|
|
var rt, et string
|
|
if len(tags) == 1 || len(tags) == 2 {
|
|
rt = tags[0]
|
|
} else {
|
|
rt = DefaultRootTag
|
|
}
|
|
if len(tags) == 2 {
|
|
et = tags[1]
|
|
} else {
|
|
et = DefaultElementTag
|
|
}
|
|
|
|
if v == nil {
|
|
if useGoXmlEmptyElemSyntax {
|
|
return []byte("<" + rt + "></" + rt + ">"), nil
|
|
}
|
|
return []byte("<" + rt + "/>"), nil
|
|
}
|
|
if reflect.TypeOf(v).Kind() == reflect.Struct {
|
|
return xml.Marshal(v)
|
|
}
|
|
|
|
var err error
|
|
s := new(string)
|
|
p := new(pretty)
|
|
|
|
var ss string
|
|
var b []byte
|
|
switch v.(type) {
|
|
case []interface{}:
|
|
ss = "<" + rt + ">"
|
|
for _, vv := range v.([]interface{}) {
|
|
switch vv.(type) {
|
|
case map[string]interface{}:
|
|
m := vv.(map[string]interface{})
|
|
if len(m) == 1 {
|
|
for tag, val := range m {
|
|
err = mapToXmlIndent(false, s, tag, val, p)
|
|
}
|
|
} else {
|
|
err = mapToXmlIndent(false, s, et, vv, p)
|
|
}
|
|
default:
|
|
err = mapToXmlIndent(false, s, et, vv, p)
|
|
}
|
|
if err != nil {
|
|
break
|
|
}
|
|
}
|
|
ss += *s + "</" + rt + ">"
|
|
b = []byte(ss)
|
|
case map[string]interface{}:
|
|
m := Map(v.(map[string]interface{}))
|
|
b, err = m.Xml(rt)
|
|
default:
|
|
err = mapToXmlIndent(false, s, rt, v, p)
|
|
b = []byte(*s)
|
|
}
|
|
|
|
return b, err
|
|
}
|
|
|
|
// Encode an arbitrary value as a pretty XML string.
|
|
// Alternative values for DefaultRootTag and DefaultElementTag can be set as:
|
|
// AnyXmlIndent( v, "", " ", myRootTag, myElementTag).
|
|
func AnyXmlIndent(v interface{}, prefix, indent string, tags ...string) ([]byte, error) {
|
|
var rt, et string
|
|
if len(tags) == 1 || len(tags) == 2 {
|
|
rt = tags[0]
|
|
} else {
|
|
rt = DefaultRootTag
|
|
}
|
|
if len(tags) == 2 {
|
|
et = tags[1]
|
|
} else {
|
|
et = DefaultElementTag
|
|
}
|
|
|
|
if v == nil {
|
|
if useGoXmlEmptyElemSyntax {
|
|
return []byte(prefix + "<" + rt + ">\n" + prefix + "</" + rt + ">"), nil
|
|
}
|
|
return []byte(prefix + "<" + rt + "/>"), nil
|
|
}
|
|
if reflect.TypeOf(v).Kind() == reflect.Struct {
|
|
return xml.MarshalIndent(v, prefix, indent)
|
|
}
|
|
|
|
var err error
|
|
s := new(string)
|
|
p := new(pretty)
|
|
p.indent = indent
|
|
p.padding = prefix
|
|
|
|
var ss string
|
|
var b []byte
|
|
switch v.(type) {
|
|
case []interface{}:
|
|
ss = "<" + rt + ">\n"
|
|
p.Indent()
|
|
for _, vv := range v.([]interface{}) {
|
|
switch vv.(type) {
|
|
case map[string]interface{}:
|
|
m := vv.(map[string]interface{})
|
|
if len(m) == 1 {
|
|
for tag, val := range m {
|
|
err = mapToXmlIndent(true, s, tag, val, p)
|
|
}
|
|
} else {
|
|
p.start = 1 // we 1 tag in
|
|
err = mapToXmlIndent(true, s, et, vv, p)
|
|
*s += "\n"
|
|
}
|
|
default:
|
|
p.start = 0 // in case trailing p.start = 1
|
|
err = mapToXmlIndent(true, s, et, vv, p)
|
|
}
|
|
if err != nil {
|
|
break
|
|
}
|
|
}
|
|
ss += *s + "</" + rt + ">"
|
|
b = []byte(ss)
|
|
case map[string]interface{}:
|
|
m := Map(v.(map[string]interface{}))
|
|
b, err = m.XmlIndent(prefix, indent, rt)
|
|
default:
|
|
err = mapToXmlIndent(true, s, rt, v, p)
|
|
b = []byte(*s)
|
|
}
|
|
|
|
return b, err
|
|
}
|