Documentation
¶
Overview ¶
Package replace 提供 OFD 包内条目的替换、新增与删除能力。
替换按包内路径(如 "Doc_0/Pages/Page_0/Content.xml")操作,不解析页面或 资源模型:命中的条目用新字节覆盖,其余条目原样搬运。由于任何字节改动都会 使已有签名摘要失效,Options.Signatures 默认丢弃签名目录;需要保留时可显式 选择 preserve 或 rewrite。
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Files ¶
Files 读取 input(文件路径、字节数据或 io.Reader),执行操作后写入 w。 同一条目可组合 OpDelete 与 OpAdd 以替换条目;该组合按删除后新增执行, 不受 operations 中两项的排列顺序影响。
Example ¶
ExampleFiles 演示替换已有的文档元数据条目,并在输出后执行严格校验。
package main
import (
"archive/zip"
"bytes"
"fmt"
"io"
"github.com/zc310/ofd/pkg/creator"
"github.com/zc310/ofd/pkg/creator/replace"
)
func replaceExampleDocument() []byte {
data, err := creator.Marshal(creator.Document{
ID: "replace-example",
Title: "替换前标题",
PageSize: creator.PageSize{Width: 100, Height: 100},
Pages: []creator.Page{{}},
})
if err != nil {
panic(err)
}
return data
}
func replaceExampleEntry(data []byte, name string) []byte {
archive, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
if err != nil {
panic(err)
}
for _, file := range archive.File {
if file.Name != name {
continue
}
r, err := file.Open()
if err != nil {
panic(err)
}
content, readErr := io.ReadAll(r)
closeErr := r.Close()
if readErr != nil {
panic(readErr)
}
if closeErr != nil {
panic(closeErr)
}
return content
}
panic("未找到 OFD 条目 " + name)
}
// ExampleFiles 演示替换已有的文档元数据条目,并在输出后执行严格校验。
func main() {
input := replaceExampleDocument()
rootXML := replaceExampleEntry(input, "OFD.xml")
updatedXML := bytes.Replace(rootXML, []byte("替换前标题"), []byte("替换后标题"), 1)
if bytes.Equal(updatedXML, rootXML) {
panic("文档标题未找到")
}
var output bytes.Buffer
err := replace.Files(input, []replace.Operation{{
Kind: replace.OpSet,
Name: "OFD.xml",
Data: updatedXML,
}}, &output, replace.Options{Validate: true, Deterministic: true})
if err != nil {
panic(err)
}
resultXML := replaceExampleEntry(output.Bytes(), "OFD.xml")
fmt.Println(bytes.Contains(resultXML, []byte("替换后标题")))
}
Output: true
Types ¶
type Operation ¶
type Operation struct {
// Kind 是操作类型。
Kind OperationKind
// Name 是包内路径,不带前导斜杠。
Name string
// Data 是 Set/Add 的新字节内容。
Data []byte
}
Operation 描述一次条目操作。
type OperationKind ¶
type OperationKind string
OperationKind 描述对某个包内条目的操作类型。
const ( // OpSet 替换已有条目,条目不存在时报错。 OpSet OperationKind = "set" // OpAdd 新增条目,条目已存在时报错。 OpAdd OperationKind = "add" // OpDelete 删除已有条目,条目不存在时报错。 OpDelete OperationKind = "delete" )
type Options ¶
type Options struct {
// Compression 是输出 ZIP 的压缩策略,空值时按条目类型自动选择。
Compression creator.CompressionMode
// CompressionLevel 是 DEFLATE 压缩级别,0 使用默认级别 5,显式范围
// 1(最快)到 9(最紧凑)。仅对实际使用 Deflate 的条目生效。
CompressionLevel int
// Deterministic 使用固定 ZIP 时间,生成可复现的结果。
Deterministic bool
// Signatures 是签名处理方式。零值等价于 creator.SignatureDrop,与包级说明
// 一致:任何字节改动都会使已有摘要失效,保留一份摘要已失效的签名比直接移除
// 更容易误导。需要保留签名条目(例如作为原始证据)时显式选 preserve。
Signatures creator.SignatureMode
// Limits 限制输入与输出的规模,零值使用默认限制。
Limits Limits
// Validate 在输出后执行严格 OFD 校验。
Validate bool
// SkipXMLCheck 关闭默认的 XML 良构检查;Set/Add 的新内容若命中 .xml 条目,
// 默认会先解析校验,防止写入格式损坏的 XML。
SkipXMLCheck bool
// OnWarning 可选,接收非致命提示,例如签名被保留但摘要已失效。
OnWarning func(string)
}
Options 控制替换输出方式。
Click to show internal directories.
Click to hide internal directories.