Xml Unmarshalling 导致 golang 中的垃圾字符

Posted

技术标签:

【中文标题】Xml Unmarshalling 导致 golang 中的垃圾字符【英文标题】:Xml Unmarshalling leads to junk characters in golang 【发布时间】:2022-01-08 16:22:18 【问题描述】:

我也是 Golang 和 XML 的新手。 我需要打开一个 XML 文件并通过 XML 解析进行一些更改并将生成的 XML 发送回 HTTP 响应(邮递员)。

对于需要使用 XML 解析将打开的字节值转换为结构模型

xmlFile,err := os.Open("sample.xml")
byteValue ,_:= ioutil.ReadAll(xmlfile)
var model structModel
xml.Unmarshal(byteValue,&model)

但在更改后将结构转换回 byteArray 时,使用 xml.Marshal 作为 byteValue,_=xml.Marshal(模型)

它会添加不需要的垃圾字符以及生成的 xml 字段数据“ ” 这被发现为 xml 中使用的换行符 所以尝试通过使用字节替换为“\n”来删除字符。编组后替换

byteValue = bytes.Replace(byteValue,[]byte("
"),[]byte("\n"),-1)

使用 struct 进行 Unmashalling 和 Marshalling 后,xml 输出显示字段的方式不同 示例 - sample.xml 中的 vmap:VMAP 和 vmap:AdBreak 文件名在生成的 XML 中分别更改为简单的 VMAP 和 AdBreak

示例 XML 是

<?xml version="1.0" encoding="UTF-8"?>
<vmap:VMAP xmlns:vmap="http://www.iab.net/vmap-1.0" version="1.0">
   <vmap:AdBreak User="u001" device="mobile">
      <Ad id="31966499.140094429862144" sequence="1">
         <Duration>00:00:15</Duration>
      </Ad>
      <Ad id="24061566.140094429860608" sequence="3">
         <Duration>00:00:15</Duration>
      </Ad>
   </vmap:AdBreak>
</vmap:VMAP>

我们得到的输出为

    <VMAP vmap="data" version="1.0">                                   **[vmap:VMAP -> VMAP]**
       <AdBreak User="user_1" device="cellular">                  **[vmap:AdBreak ->AdBreak]**
           <Ad id="31966499.140094429862144" sequence="1">
               <Duration>00:00:15</Duration>
           </Ad>
           <Ad id="24061566.140094429860608" sequence="3">
               <Duration>00:00:15</Duration>
           </Ad>
       </AdBreak>
   </VMAP>

并且用于该操作的结构取自这个tool

结构是

type VMAP struct 
    XMLName xml.Name `xml:"VMAP"`
    Text    string   `xml:",chardata"`
    Vmap    string   `xml:"vmap,attr"`
    Version string   `xml:"version,attr"`
    AdBreak struct 
        Text   string `xml:",chardata"`
        User   string `xml:"User,attr"`
        Device string `xml:"device,attr"`
        Ad     []struct 
            Text     string `xml:",chardata"`
            ID       string `xml:"id,attr"`
            Sequence string `xml:"sequence,attr"`
            Duration string `xml:"Duration"`
         `xml:"Ad"`
     `xml:"AdBreak"`

现在请帮助我获得与示例输入 xml 格式相同的输出,例如 xml 版本,并且 vmap:VMAP 和 vmap:adBreak 不应从给定格式更改。

【问题讨论】:

【参考方案1】:

“垃圾”字符是,chardata 字段收集的元素之间的数据,即

Text string `json:",chardata"`

如果您不想要中间数据,请删除 ,chardata 字段。


不支持开箱即用的命名空间前缀处理。请参阅问题#9519。

你必须做一些工作:

要生成以命名空间为前缀的元素,您需要自定义 xml.Marshaler

type MyElem struct  /* ... */ 

func (e MyElem) MarshalXML(e *xml.Encoder, start xml.StartElement) error 
    type T MyElem
    start.Name.Local = "my_prefix:" + start.Name.Local
    return e.EncodeElement(T(e), start)

要生成以命名空间为前缀的属性,您需要一个自定义 xml.MarshalerAttr

type MyAttr string

func (a MyAttr) MarshalXMLAttr(n xml.Name) (attr xml.Attr, err error) 
    attr.Name.Local = "my_prefix:" + n.Local
    attr.Value = string(a)
    return out, nil

试试playground。

【讨论】:

以上是关于Xml Unmarshalling 导致 golang 中的垃圾字符的主要内容,如果未能解决你的问题,请参考以下文章

Jaxb - Unmarshalling

Akka(34): Http:Unmarshalling,from Json

akka-http 错误:找不到参数 um 的隐式值:akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller

CS: Marshalling and Unmarshalling, Serialization and Unserialization

Unmarshalling Error: 意外的元素的问题的解决

如何修复 Android 中偏移 YYY 处的 Unmarshalling unknown type code XXX?