【问题标题】:Modify data in xml files using Golang使用 Golang 修改 xml 文件中的数据
【发布时间】:2018-10-11 20:50:09
【问题描述】:

我想将 lastModifiedBy 字段从 Tom Hanks 更改为 Jerry Garcia。我使用了这个 repo:https://github.com/clbanning/mxj/blob/master/xml.go 将 xml 字节解析为映射。但是,有些字段被遗漏了。

有什么简单的方法可以更改该字段并且只更改该字段?有数百个这样的文件,所以我需要以编程方式进行。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties 
 xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core- 
 properties" xmlns:dc="http://purl.org/dc/elements/1.1/" 
 xmlns:dcterms="http://purl.org/dc/terms/" 
 xmlns:dcmitype="http://purl.org/dc/dcmitype/" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title></dc:title> 
<dc:subject></dc:subject><dc:creator>John Kerry</dc:creator> 
<cp:keywords></cp:keywords><dc:description></dc:description> 
<cp:lastModifiedBy>TomHanks</cp:lastModifiedBy><cp:revision>6</cp:revision> 
<dcterms:created xsi:type="dcterms:W3CDTF">2018-02- 
20T18:08:00Z</dcterms:created><dcterms:modified 
xsi:type="dcterms:W3CDTF">2018-04-24T19:43:00Z</dcterms:modified> 
</cp:coreProperties>

【问题讨论】:

  • 我怀疑在重新创建的 xml 中重新创建所有命名空间和其他属性会有些困难。换句话说,您可能会正确解析它并在某处提出“TomHanks”,但是当您将其写回为 xml 时,您会丢失文档中的一些信息。 go 是适合这项工作的工具吗?使用sedperl 之类的东西是否会更好,并将其视为文本替换?
  • 这就是我开始想的......这里很头疼哈哈,因为我有很多关于打开文件的 go 代码等等。需要在 Windows 平台上运行,因此不确定 bash 是否会在 Windows 中作为可执行文件运行。

标签: arrays xml string go


【解决方案1】:

也许就这样(最简单的工作)然后在替换之后进行 xml 解析?不确定 TomHanks => Jerry Garcia 是否真的总是一样的,或者你必须参数化它。

package main

import (
    "fmt"
    "strings"
)


var xmlRaw = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties 
 xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core- 
 properties" xmlns:dc="http://purl.org/dc/elements/1.1/" 
 xmlns:dcterms="http://purl.org/dc/terms/" 
 xmlns:dcmitype="http://purl.org/dc/dcmitype/" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title></dc:title> 
<dc:subject></dc:subject><dc:creator>John Kerry</dc:creator> 
<cp:keywords></cp:keywords><dc:description></dc:description> 
<cp:lastModifiedBy>TomHanks</cp:lastModifiedBy><cp:revision>6</cp:revision> 
<dcterms:created xsi:type="dcterms:W3CDTF">2018-02- 
20T18:08:00Z</dcterms:created><dcterms:modified 
xsi:type="dcterms:W3CDTF">2018-04-24T19:43:00Z</dcterms:modified> 
</cp:coreProperties>`

type decoder struct {

}

func main() {

    fmt.Println(strings.Replace(xmlRaw, "TomHanks", "Jerry Garcia", 1))
}

https://play.golang.org/p/viTLElQxesM

这证明了我所描述的问题:

package main

import (
    "encoding/xml"
    "fmt"
)

var xmlRaw = []byte(`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties 
 xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core- 
 properties" xmlns:dc="http://purl.org/dc/elements/1.1/" 
 xmlns:dcterms="http://purl.org/dc/terms/" 
 xmlns:dcmitype="http://purl.org/dc/dcmitype/" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title></dc:title> 
<dc:subject></dc:subject><dc:creator>John Kerry</dc:creator> 
<cp:keywords></cp:keywords><dc:description></dc:description> 
<cp:lastModifiedBy>TomHanks</cp:lastModifiedBy><cp:revision>6</cp:revision> 
<dcterms:created xsi:type="dcterms:W3CDTF">2018-02- 
20T18:08:00Z</dcterms:created><dcterms:modified 
xsi:type="dcterms:W3CDTF">2018-04-24T19:43:00Z</dcterms:modified> 
</cp:coreProperties>`)

type decoder struct {
    Keywords       string `xml:"keywords"`
    LastModifiedBy string `xml:"lastModifiedBy"`
    //.. more xml
}

func main() {
    d := decoder{}
    if err := xml.Unmarshal(xmlRaw, &d); err != nil {
        panic(err)
    }
    fmt.Println(d.LastModifiedBy)
    d.LastModifiedBy = "Jerry Garcia"
    bytes, err := xml.Marshal(d)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(bytes))

}

https://play.golang.org/p/aYa01_3UE5e

输出:

TomHanks

<decoder><keywords></keywords><lastModifiedBy>Jerry Garcia</lastModifiedBy></decoder>

【讨论】:

  • 无法获取 cp:coreProperties,因为 go 不喜欢 cp 和 coreProperties 之间的冒号。我正在尝试使用字符串操作来获取数据。不确定是否是最好的方法,但我会看看会发生什么。
  • @Gofurther:您不要使用冒号引用元素名称,这是命名空间前缀和实际名称之间的分隔符。
【解决方案2】:
<cp:lastModifiedBy>JerryGarcia</cp:lastModifiedBy><cp:revision>6</cp:revision> 

删除 TomHanks 并写 JerryGarcia

【讨论】:

  • 不幸的是,它必须处理大约 50,000 个文件
  • 使用 for 循环 ;)
  • 但我如何访问该字段?
  • 创建一个通过标签名 cp:lastModifiedBy 获取元素的变量,并在 for 循环中使用它。然后在 for 循环中更改该变量的值。
  • 是的,那很好。不知道如何去获取该标签名称。 Go 的 xml 包中似乎没有任何内容。你有什么主意吗?非常感谢。
猜你喜欢
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多