Golang中如何避免XML属性重复

Golang中如何避免XML属性重复 你好, 我是Go语言的新手,发现学习它很有趣。

我正在编写一个将CSV文件转换为XML文件的代码。当我执行代码时,能够生成一个XML文件,但输出结果不符合预期。

期望的输出:

</Data <Header </Attribute1 </Attribute2 </Header <Item1 <Name <Address <Country </item1 <Item2 <Name <Address <Country </item2 </Data

然而,当我执行我的代码时,它在每个<Item><Name>等元素之前重复了<Header><Attribute>

谢谢


更多关于Golang中如何避免XML属性重复的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

发布你代码的相关部分可能会有所帮助,因为如果没有这些内容,就无法着手尝试找出问题所在,并以任何有意义的方式回答这个问题。

更多关于Golang中如何避免XML属性重复的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


请查看这个小型的 xml 包以了解其工作原理。同时,那里也有一个示例。

GitHub

GitHub

头像

geosoft1/xml

xml 包实现了对 RFC 4825 中定义的 XML 的编码和解码,作为标准 xml 包的高级封装。 - geosoft1/xml

在Go中生成XML时,属性重复通常是由于结构体字段标签定义不当或编码器使用错误导致的。以下是解决方案和示例代码:

问题分析

根据你的描述,<Header><Attribute>在每个<Item>前重复出现,这通常是因为:

  1. 结构体嵌套不正确
  2. XML编码器配置问题
  3. 切片或数组处理错误

解决方案

1. 正确的结构体定义

package main

import (
    "encoding/xml"
    "fmt"
    "os"
)

type Data struct {
    XMLName xml.Name `xml:"Data"`
    Header  Header   `xml:"Header"`
    Items   []Item   `xml:"Item"`
}

type Header struct {
    Attribute1 string `xml:"Attribute1"`
    Attribute2 string `xml:"Attribute2"`
}

type Item struct {
    XMLName xml.Name `xml:"Item"`
    Name    string   `xml:"Name"`
    Address string   `xml:"Address"`
    Country string   `xml:"Country"`
}

2. 生成XML的完整示例

func main() {
    data := Data{
        Header: Header{
            Attribute1: "Value1",
            Attribute2: "Value2",
        },
        Items: []Item{
            {
                Name:    "John Doe",
                Address: "123 Main St",
                Country: "USA",
            },
            {
                Name:    "Jane Smith",
                Address: "456 Oak Ave",
                Country: "Canada",
            },
        },
    }

    // 生成XML
    output, err := xml.MarshalIndent(data, "", "  ")
    if err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }

    // 添加XML头
    xmlData := xml.Header + string(output)
    
    // 写入文件
    err = os.WriteFile("output.xml", []byte(xmlData), 0644)
    if err != nil {
        fmt.Printf("Error writing file: %v\n", err)
        return
    }
    
    fmt.Println("XML文件生成成功")
}

3. 如果使用xml.Marshal遇到属性重复

使用xml:"attr"标签时确保正确使用:

type Item struct {
    XMLName xml.Name `xml:"Item"`
    ID      string   `xml:"id,attr"`  // 作为属性
    Name    string   `xml:"Name"`
    Address string   `xml:"Address"`
    Country string   `xml:"Country"`
}

// 使用示例
item := Item{
    ID:      "1",
    Name:    "Test",
    Address: "Test Address",
    Country: "Test Country",
}

4. 避免重复的编码器配置

func generateXML(data Data) error {
    file, err := os.Create("output.xml")
    if err != nil {
        return err
    }
    defer file.Close()

    encoder := xml.NewEncoder(file)
    encoder.Indent("", "  ")
    
    // 写入XML头
    if _, err := file.WriteString(xml.Header); err != nil {
        return err
    }
    
    // 编码数据
    if err := encoder.Encode(data); err != nil {
        return err
    }
    
    return encoder.Flush()
}

5. 检查CSV转换逻辑

确保CSV到结构体的转换正确:

func convertCSVToItems(csvData [][]string) []Item {
    var items []Item
    
    for i, row := range csvData {
        if i == 0 {
            continue // 跳过标题行
        }
        
        if len(row) >= 3 {
            item := Item{
                Name:    row[0],
                Address: row[1],
                Country: row[2],
            }
            items = append(items, item)
        }
    }
    
    return items
}

关键点

  1. 确保HeaderData结构体中只定义一次
  2. Items应该是一个切片,而不是在循环中重复添加Header
  3. 使用正确的XML标签:xml:"ElementName"用于元素,xml:"name,attr"用于属性
  4. 避免在循环中重新创建或重复添加父级元素

运行上述代码将生成正确的XML结构,<Header>只出现一次,后面跟着所有的<Item>元素。

回到顶部