Измените данные в файлах xml с помощью Golang

Я хочу изменить поле lastModifiedBy с Тома Хэнкса на Джерри Гарсиа. Я использовал это репо: 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, вы потеряете некоторую информацию в документе. Подходит ли идти для этой работы? Может быть, вам лучше взять что-то вроде sed или perl и рассматривать это как замену текста?

Slabgorb 01.05.2018 22:10

Это то, что я начинаю думать ... большая головная боль здесь, ха-ха, потому что у меня за этим стоит много кода go с открытием файлов и тому подобное. должен работать на платформе Windows, поэтому не был уверен, будет ли bash работать как исполняемый файл в Windows.

Gofurther 01.05.2018 22:13
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
2
2 161
2

Ответы 2

<cp:lastModifiedBy>JerryGarcia</cp:lastModifiedBy><cp:revision>6</cp:revision> 

Удалите TomHanks и напишите JerryGarcia

К сожалению, это нужно сделать с 50 000 файлов.

Gofurther 01.05.2018 21:58

Используйте цикл for;)

lextragon 01.05.2018 22:01

Но как мне получить доступ к этому полю?

Gofurther 01.05.2018 22:02

Создайте переменную, которая получает элемент по имени тега cp: lastModifiedBy, и используйте ее в цикле for. Затем измените значение этой переменной внутри цикла for.

lextragon 01.05.2018 22:09

Да, было бы хорошо. Не знаю, как получить это имя тега. Кажется, что внутри xml-пакета Go ничего нет. Есть ли у вас какие-либо идеи? Очень признателен.

Gofurther 01.05.2018 22:19

@Gof Further: Я не уверен, что вы имеете в виду, говоря, что ничего не входит в xml-пакет go. Вы можете декодировать в структуры или перебирать декодер по одному токену за раз. Единственная проблема может заключаться в том, что кодировщик не поддерживает обратное кодирование с теми же префиксами пространства имен и будет иметь атрибут xmlns для каждого тега.

JimB 01.05.2018 22:41

может быть, тогда (самая простая вещь, которая работает), а затем после замены выполнить синтаксический анализ 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 01.05.2018 22:49

@Gof Далее: вы не ссылаетесь на имя элемента с двоеточием, это разделитель между префиксом пространства имен и фактическим именем.

JimB 01.05.2018 23:03

Другие вопросы по теме