xml 字符编码互转
This commit is contained in:
parent
32941ea584
commit
e540b8f964
9
go.mod
9
go.mod
@ -2,18 +2,23 @@ module git.skcks.cn/Shikong/go-gb28181
|
||||
|
||||
go 1.23.5
|
||||
|
||||
require github.com/emiago/sipgo v0.28.0
|
||||
require (
|
||||
github.com/emiago/sipgo v0.28.0
|
||||
github.com/icholy/digest v1.1.0
|
||||
golang.org/x/net v0.34.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
||||
github.com/gobwas/httphead v0.1.0 // indirect
|
||||
github.com/gobwas/pool v0.2.1 // indirect
|
||||
github.com/gobwas/ws v1.4.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/icholy/digest v1.1.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/rs/zerolog v1.33.0 // indirect
|
||||
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
)
|
||||
|
6
go.sum
6
go.sum
@ -1,3 +1,5 @@
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
@ -40,11 +42,15 @@ github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b h1:gQZ0qzfKHQIybL
|
||||
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
193
pkg/utils/xml_test.go
Normal file
193
pkg/utils/xml_test.go
Normal file
@ -0,0 +1,193 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/axgle/mahonia"
|
||||
"golang.org/x/net/html/charset"
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
"golang.org/x/text/transform"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const GB2312_XML = `
|
||||
<?xml version="1.0" encoding="GB2312" ?>
|
||||
<Response>
|
||||
<CmdType>Catalog</CmdType>
|
||||
<SumNum>2</SumNum>
|
||||
<DeviceList Num="2">
|
||||
<Item>
|
||||
<Name>模拟设备名称</Name>
|
||||
<Manufacturer>gb28181-docking-platform</Manufacturer>
|
||||
<Model/>
|
||||
<Owner/>
|
||||
<Block/>
|
||||
<Address/>
|
||||
<Parental>0</Parental>
|
||||
<SafetyWay>0</SafetyWay>
|
||||
<RegisterWay>1</RegisterWay>
|
||||
<CertNum/>
|
||||
<Certifiable>0</Certifiable>
|
||||
<ErrCode>0</ErrCode>
|
||||
<EndTime/>
|
||||
<Secrecy>0</Secrecy>
|
||||
<Port/>
|
||||
<Password/>
|
||||
<Status>ON</Status>
|
||||
<Longitude>0.0</Longitude>
|
||||
<Latitude>0.0</Latitude>
|
||||
<DeviceID>44050100001310000010</DeviceID>
|
||||
<CivilCode/>
|
||||
<ParentID/>
|
||||
<IPAddress/>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name>模拟设备名称</Name>
|
||||
<Manufacturer>gb28181-docking-platform</Manufacturer>
|
||||
<Model/>
|
||||
<Owner/>
|
||||
<Block/>
|
||||
<Address/>
|
||||
<Parental>0</Parental>
|
||||
<SafetyWay>0</SafetyWay>
|
||||
<RegisterWay>1</RegisterWay>
|
||||
<CertNum/>
|
||||
<Certifiable>0</Certifiable>
|
||||
<ErrCode>0</ErrCode>
|
||||
<EndTime/>
|
||||
<Secrecy>0</Secrecy>
|
||||
<Port/>
|
||||
<Password/>
|
||||
<Status>ON</Status>
|
||||
<Longitude>0.0</Longitude>
|
||||
<Latitude>0.0</Latitude>
|
||||
<DeviceID>44050100001310000010</DeviceID>
|
||||
<CivilCode/>
|
||||
<ParentID/>
|
||||
<IPAddress/>
|
||||
</Item>
|
||||
</DeviceList>
|
||||
<SN>1</SN>
|
||||
<DeviceID>44050100001110000010</DeviceID>
|
||||
</Response>
|
||||
`
|
||||
|
||||
type Catalog struct {
|
||||
XMLName xml.Name `xml:"Response"`
|
||||
CmdType string `xml:"CmdType"`
|
||||
SumNum string `xml:"SumNum"`
|
||||
DeviceList struct {
|
||||
XMLName xml.Name `xml:"DeviceList"`
|
||||
Num string `xml:"Num,attr"`
|
||||
Item []struct {
|
||||
XMLName xml.Name `xml:"Item"`
|
||||
Name string `xml:"Name"`
|
||||
Manufacturer string `xml:"Manufacturer"`
|
||||
Model string `xml:"Model"`
|
||||
Owner string `xml:"Owner"`
|
||||
Block string `xml:"Block"`
|
||||
Address string `xml:"Address"`
|
||||
Parental string `xml:"Parental"`
|
||||
SafetyWay string `xml:"SafetyWay"`
|
||||
RegisterWay string `xml:"RegisterWay"`
|
||||
CertNum string `xml:"CertNum"`
|
||||
Certifiable string `xml:"Certifiable"`
|
||||
ErrCode string `xml:"ErrCode"`
|
||||
EndTime string `xml:"EndTime"`
|
||||
Secrecy string `xml:"Secrecy"`
|
||||
Port string `xml:"Port"`
|
||||
Password string `xml:"Password"`
|
||||
Status string `xml:"Status"`
|
||||
Longitude string `xml:"Longitude"`
|
||||
Latitude string `xml:"Latitude"`
|
||||
DeviceID string `xml:"DeviceID"`
|
||||
CivilCode string `xml:"CivilCode"`
|
||||
ParentID string `xml:"ParentID"`
|
||||
IPAddress string `xml:"IPAddress"`
|
||||
} `xml:"Item"`
|
||||
} `xml:"DeviceList"`
|
||||
SN string `xml:"SN"`
|
||||
DeviceID string `xml:"DeviceID"`
|
||||
}
|
||||
|
||||
func TestGB2312XML(t *testing.T) {
|
||||
decoder := xml.NewDecoder(strings.NewReader(GB2312_XML))
|
||||
decoder.CharsetReader = func(c string, input io.Reader) (io.Reader, error) {
|
||||
reader, err := charset.NewReader(input, c)
|
||||
return reader, err
|
||||
}
|
||||
|
||||
obj := Catalog{}
|
||||
err := decoder.Decode(&obj)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%+v\n", obj)
|
||||
|
||||
marshal := &bytes.Buffer{}
|
||||
encoder := xml.NewEncoder(marshal)
|
||||
encoder.Indent("", " ")
|
||||
err = encoder.Encode(&obj)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = encoder.Close()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
xmlStr := marshal.String()
|
||||
cs := strings.ToUpper("gb2312")
|
||||
xmlStr = fmt.Sprintf("<?xml version=\"1.0\" encoding=\"%s\" ?>\r\n%s", cs, xmlStr)
|
||||
|
||||
xmlBytes := &bytes.Buffer{}
|
||||
err = func() (err error) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
fmt.Println("使用 simplifiedchinese 转义")
|
||||
writer := transform.NewWriter(xmlBytes, simplifiedchinese.HZGB2312.NewEncoder())
|
||||
writer.Write([]byte(xmlStr))
|
||||
_ = writer.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
enc := mahonia.NewEncoder(cs)
|
||||
xmlStr = enc.ConvertString(xmlStr)
|
||||
xmlBytes.Write([]byte(xmlStr))
|
||||
return nil
|
||||
}()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(xmlStr)
|
||||
|
||||
tmpFile, _ := filepath.Abs(filepath.Join(os.TempDir(), "gb2312.xml"))
|
||||
fmt.Println(tmpFile)
|
||||
openFile, err := os.OpenFile(tmpFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = openFile.Write(xmlBytes.Bytes())
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_ = openFile.Close()
|
||||
|
||||
readAll, err := io.ReadAll(openFile)
|
||||
decoder = xml.NewDecoder(bytes.NewBuffer(readAll))
|
||||
decoder.CharsetReader = func(c string, input io.Reader) (io.Reader, error) {
|
||||
reader, err := charset.NewReader(input, c)
|
||||
return reader, err
|
||||
}
|
||||
decoder.Decode(&obj)
|
||||
fmt.Printf("%+v\n", obj)
|
||||
}
|
@ -18,8 +18,7 @@ func TestClient(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
|
||||
ua, _ := sipgo.NewUA(
|
||||
sipgo.WithUserAgent("44050100002000000002"),
|
||||
sipgo.WithUserAgentHostname("10.10.10.20:5099"))
|
||||
sipgo.WithUserAgentHostname("44050100002000000002@10.10.10.20:5099"))
|
||||
|
||||
srv, _ := sipgo.NewServer(ua) // Creating server handle
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user