xml.go 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /**
  2. * Copyright (c) 2022 Yansen Zhang
  3. * wxcomponent is licensed under Mulan PSL v2.
  4. * You can use this software according to the terms and conditions of the Mulan PSL v2.
  5. * You may obtain a copy of Mulan PSL v2 at:
  6. * http://license.coscl.org.cn/MulanPSL2
  7. * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
  8. * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
  9. * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
  10. * See the Mulan PSL v2 for more details.
  11. **/
  12. package encrypt
  13. import (
  14. "encoding/xml"
  15. "io"
  16. "regexp"
  17. )
  18. // 简易版本的 xml 解析, 实现将 单层 xml 解析到 map[string]string
  19. // XMLMap xml 转换 map
  20. type XMLMap map[string]string
  21. // XMLElement xml 转换 element
  22. type XMLElement struct {
  23. XMLName xml.Name
  24. Value string `xml:",chardata"`
  25. }
  26. // XMLCDATA xml 转换 cdata
  27. type XMLCDATA struct {
  28. XMLName xml.Name
  29. Value string `xml:",cdata"`
  30. }
  31. // UnmarshalXML xml.Unmarshaler 接口实现
  32. // 参考 https://stackoverflow.com/questions/30928770/marshall-map-to-xml-in-go
  33. func (m *XMLMap) UnmarshalXML(d *xml.Decoder, _ xml.StartElement) error {
  34. for {
  35. ele := XMLElement{}
  36. err := d.Decode(&ele)
  37. if err == io.EOF {
  38. break
  39. } else if err != nil {
  40. return err
  41. }
  42. // 忽略 Space
  43. (*m)[ele.XMLName.Local] = ele.Value
  44. }
  45. return nil
  46. }
  47. // MarshalXML xml.Marshaler 接口实现
  48. // 参考 https://stackoverflow.com/questions/30928770/marshall-map-to-xml-in-go
  49. func (m *XMLMap) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
  50. if m == nil || len(*m) == 0 {
  51. return nil
  52. }
  53. if start.Name.Local == "XMLMap" {
  54. start.Name.Local = "xml"
  55. }
  56. if err := e.EncodeToken(start); err != nil {
  57. return err
  58. }
  59. regx, err := regexp.Compile(`<!\[CDATA\[(.*)\]\]>`)
  60. if err != nil {
  61. return err
  62. }
  63. for k, v := range *m {
  64. res := regx.FindAllStringSubmatch(v, -1)
  65. if len(res) > 0 {
  66. t := XMLCDATA{
  67. XMLName: xml.Name{
  68. Space: "",
  69. Local: k,
  70. },
  71. Value: res[0][1],
  72. }
  73. if err := e.Encode(&t); err != nil {
  74. return err
  75. }
  76. } else {
  77. t := XMLElement{
  78. XMLName: xml.Name{
  79. Space: "",
  80. Local: k,
  81. },
  82. Value: v,
  83. }
  84. if err := e.Encode(&t); err != nil {
  85. return err
  86. }
  87. }
  88. }
  89. return e.EncodeToken(start.End())
  90. }