Table of Contents
问题内容
解决方法
Home Backend Development Golang Why (encoder).EncodeElement ignores ',innerxml' tag?

Why (encoder).EncodeElement ignores ',innerxml' tag?

Feb 09, 2024 am 08:03 AM

为什么 (encoder).EncodeElement 忽略“,innerxml”标签?

php小编小新在这里为大家解答一个常见问题:“为什么 (encoder).EncodeElement 忽略“,innerxml”标签?”。这个问题涉及到在使用 (encoder).EncodeElement 方法时,为什么会出现无法编码 innerxml 标签的情况。下面我们将详细回答这个问题,帮助读者更好地理解和解决相关问题。

问题内容

用途:我有一个 xml 文档,其中包含许多混合内容 cdata 元素,我需要以编程方式编辑这些元素。令人烦恼的是,由于 cdata 元素具有其他/混合内容,默认的“,cdata”标记无法正常工作(根据 xml 规范)。如果您对此具体细节有疑问,请告诉我。

问题:在下面的简化示例中,我将其中包含 cdata 的元素标记为“,innerxml”,以便自己处理前缀/后缀。通过解组,一切都按预期工作,但是通过编组(编码),特殊字符被转义。当标签明确表示不转义时(通过“,innerxml”标签),为什么 EncodeElement 方法会转义特殊字符?当我在文档中读到此方法时,它让我参考 xml.Marshal 方法,其中包含以下内容:

<code>
a field with tag &quot;,innerxml&quot; is written verbatim, not subject to the usual marshaling procedure.
</code>
Copy after login

示例:

以下是代码(也可在 https://go.dev/play/p/MH_ONAVaG_1 获取):

package main

import (
    &quot;encoding/xml&quot;
    &quot;fmt&quot;
    &quot;strings&quot;
)

var xmlFile string = `&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;statusdb&gt;
  &lt;status date=&quot;today&quot;&gt;
      &lt;![CDATA[today is &lt; yesterday]]&gt;
  &lt;/status&gt;
  &lt;status  date=&quot;yesterday&quot;&gt;
      &lt;![CDATA[PM,
      1. there are issues with the marshaller
      2. i don't know how to solve them]]&gt;
  &lt;/status&gt;
&lt;/statusdb&gt;`

type statusDB struct {
    Status []*status `xml:&quot;status&quot;`
}

type status struct {
    Text string `xml:&quot;,innerxml&quot;`
    Date string `xml:&quot;date,attr&quot;`
}

type statusMarshaller status

func main() {

    var projectStatus statusDB

    err := xml.Unmarshal([]byte(xmlFile), &amp;projectStatus)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(&quot;In Go: \&quot;&quot; + projectStatus.Status[0].Text + &quot;\&quot;&quot;)
    fmt.Println(&quot;In Go: \&quot;&quot; + projectStatus.Status[1].Text + &quot;\&quot;&quot;)
    x, err := xml.MarshalIndent(projectStatus, &quot;&quot;, &quot;  &quot;)
    if err != nil {
        fmt.Println(err)
        return
    }
    //why this is not printing properly
    fmt.Printf(&quot;%s\n&quot;, x)
}

func (tagElement *status) UnmarshalXML(d *xml.Decoder, se xml.StartElement) error {
    temp := statusMarshaller{}
    d.DecodeElement(&amp;temp, &amp;se)
    temp.Text = strings.TrimSpace(temp.Text)
    temp.Text = strings.TrimPrefix(temp.Text, &quot;&lt;![CDATA[&quot;)
    temp.Text = strings.TrimSuffix(temp.Text, &quot;]]&gt;&quot;)
    *tagElement = status(temp)
    return nil
}

func (tagElement status) MarshalXML(d *xml.Encoder, se xml.StartElement) error {
    tagElement.Text = &quot;&lt;![CDATA[&quot; + tagElement.Text + &quot;]]&gt;&quot;
    temp, _ := xml.Marshal(statusMarshaller(tagElement))
    return d.EncodeElement(temp, se)
}
Copy after login

此代码返回以下内容:

In Go: &quot;today is &lt; yesterday&quot;
In Go: &quot;PM,
      1. there are issues with the marshaller
      2. i don't know how to solve them&quot;
&lt;statusDB&gt;
  &lt;status&gt;&amp;lt;statusMarshaller date=&amp;#34;today&amp;#34;&amp;gt;&amp;lt;![CDATA[today is &amp;lt; yesterday]]&amp;gt;&amp;lt;/statusMarshaller&amp;gt;&lt;/status&gt;
  &lt;status&gt;&amp;lt;statusMarshaller date=&amp;#34;yesterday&amp;#34;&amp;gt;&amp;lt;![CDATA[PM,&amp;#xA;      1. there are issues with the marshaller&amp;#xA;      2. i don&amp;#39;t know how to solve them]]&amp;gt;&amp;lt;/statusMarshaller&amp;gt;&lt;/status&gt;
&lt;/statusDB&gt;

Program exited.
Copy after login

结论:有人可以解释一下为什么 xml 包会这样做,以及潜在的解决方法是什么?

谢谢!

解决方法

当然,如果包中的 cdata 允许混合元素,那就太好了,但现在我已经找到了解决方法,即上面的代码,进行了一些小更改,以便不在 marhshalXML 中的 statusMarshaller 类型上调用“marshal”功能。相反,我只将 tagElement 转换为 statusMarshaller 类型,然后对该元素进行编码。请参阅以下详细信息:

修订历史记录:

  1. 修改了 marshalXML 函数中的第二行以删除对 xml.marshal 的调用
  2. 修改了状态结构以包含 XMLName 成员,以便维护 XML 元素名称(在生成的 xml 元素中保留“status”而不是“statusMarshaller”
package main

import (
    &quot;encoding/xml&quot;
    &quot;fmt&quot;
    &quot;strings&quot;
)

var xmlFile string = `&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;statusdb&gt;
  &lt;status date=&quot;today&quot;&gt;
      &lt;![CDATA[today is &lt; yesterday]]&gt;
  &lt;/status&gt;
  &lt;status  date=&quot;yesterday&quot;&gt;
      &lt;![CDATA[PM,
      1. there are issues with the marshaller
      2. i don't know how to solve them]]&gt;
  &lt;/status&gt;
&lt;/statusdb&gt;`

type statusDB struct {
    Status []*status `xml:&quot;status&quot;`
}

type status struct {
    XMLName xml.Name
    Text string `xml:&quot;,innerxml&quot;`
    Date string `xml:&quot;date,attr&quot;`
}

type statusMarshaller status

func main() {

    var projectStatus statusDB

    err := xml.Unmarshal([]byte(xmlFile), &amp;projectStatus)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(&quot;In Go: \&quot;&quot; + projectStatus.Status[0].Text + &quot;\&quot;&quot;)
    fmt.Println(&quot;In Go: \&quot;&quot; + projectStatus.Status[1].Text + &quot;\&quot;&quot;)
    x, err := xml.MarshalIndent(projectStatus, &quot;&quot;, &quot;  &quot;)
    if err != nil {
        fmt.Println(err)
        return
    }
    //why this is not printing properly
    fmt.Printf(&quot;%s\n&quot;, x)
}

func (tagElement *status) UnmarshalXML(d *xml.Decoder, se xml.StartElement) error {
    temp := statusMarshaller{}
    d.DecodeElement(&amp;temp, &amp;se)
    temp.Text = strings.TrimSpace(temp.Text)
    temp.Text = strings.TrimPrefix(temp.Text, &quot;&lt;![CDATA[&quot;)
    temp.Text = strings.TrimSuffix(temp.Text, &quot;]]&gt;&quot;)
    *tagElement = status(temp)
    return nil
}

func (tagElement status) MarshalXML(d *xml.Encoder, se xml.StartElement) error {
    tagElement.Text = &quot;&lt;![CDATA[&quot; + tagElement.Text + &quot;]]&gt;&quot;
    temp := statusMarshaller(tagElement)
    return d.EncodeElement(temp, se)
}
Copy after login

The above is the detailed content of Why (encoder).EncodeElement ignores ',innerxml' tag?. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot Article Tags

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Go language pack import: What is the difference between underscore and without underscore? Go language pack import: What is the difference between underscore and without underscore? Mar 03, 2025 pm 05:17 PM

Go language pack import: What is the difference between underscore and without underscore?

How to implement short-term information transfer between pages in the Beego framework? How to implement short-term information transfer between pages in the Beego framework? Mar 03, 2025 pm 05:22 PM

How to implement short-term information transfer between pages in the Beego framework?

How do I write mock objects and stubs for testing in Go? How do I write mock objects and stubs for testing in Go? Mar 10, 2025 pm 05:38 PM

How do I write mock objects and stubs for testing in Go?

How can I use tracing tools to understand the execution flow of my Go applications? How can I use tracing tools to understand the execution flow of my Go applications? Mar 10, 2025 pm 05:36 PM

How can I use tracing tools to understand the execution flow of my Go applications?

How to convert MySQL query result List into a custom structure slice in Go language? How to convert MySQL query result List into a custom structure slice in Go language? Mar 03, 2025 pm 05:18 PM

How to convert MySQL query result List into a custom structure slice in Go language?

How can I define custom type constraints for generics in Go? How can I define custom type constraints for generics in Go? Mar 10, 2025 pm 03:20 PM

How can I define custom type constraints for generics in Go?

How to write files in Go language conveniently? How to write files in Go language conveniently? Mar 03, 2025 pm 05:15 PM

How to write files in Go language conveniently?

How do I write benchmarks that accurately reflect real-world performance in Go? How do I write benchmarks that accurately reflect real-world performance in Go? Mar 10, 2025 pm 05:36 PM

How do I write benchmarks that accurately reflect real-world performance in Go?

See all articles