xmlstruct

package module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2023 License: MIT Imports: 18 Imported by: 0

README

go-xmlstruct

PkgGoDev

Generate Go structs from multiple XML documents.

What does go-xmlstruct do and why should I use it?

go-xmlstruct generates Go structs from XML documents. Alternatively put, go-xmlstruct infers XML schemas from one or more example XML documents. For example, given this XML document, go-xmlstruct generates this Go source code.

Compared to existing Go struct generators like zek, XMLGen, and chidley, go-xmlstruct:

  • Takes multiple XML documents as input.
  • Generates field types of bool, int, string, or time.Time as appropriate.
  • Creates named types for all elements.
  • Handles optional attributes and elements.
  • Handles repeated attributes and elements.
  • Ignores empty chardata.
  • Provides a CLI for simple use.
  • Usable as a Go package for advanced use, including configurable field naming.

go-xmlstruct is useful for quick-and-dirty unmarshalling of arbitrary XML documents, especially when you have no schema or the schema is extremely complex and you want something that "just works" with the documents you have.

Install

Install the goxmlstruct CLI with:

$ go install github.com/twpayne/go-xmlstruct/cmd/goxmlstruct@latest

Example

Feed goxmlstruct the simple XML document:

<parent>
  <child flag="true">
    chardata
  </child>
</parent>

by running:

$ echo '<parent><child flag="true">text</child></parent>' | goxmlstruct

This produces the output:

// This file is automatically generated. DO NOT EDIT.

package main

type Parent struct {
        Child struct {
                Flag     bool   `xml:"flag,attr"`
                CharData string `xml:",chardata"`
        } `xml:"child"`
}

This demonstrates:

  • A Go struct is generated from the structure of the input XML document.
  • Attributes, child elements, and chardata are all considered.
  • Field names are generated automatically.
  • Field types are detected automatically.

For a full list of options to the goxmlstruct CLI run:

$ goxmlstruct -help

You can run a more advanced example with:

$ git clone https://github.com/twpayne/go-xmlstruct.git
$ cd go-xmlstruct
$ goxmlstruct internal/tests/gpx/testdata/*.gpx

This demonstrates generating a Go struct from multiple XML complex documents.

For an example of configurable field naming and named types by using go-xmlstruct as a package, see internal/tests/play/play_test.go.

For an example of a complex schema, see internal/tests/aixm/aixm_test.go.

How does go-xmlstruct work?

Similar to go-jsonstruct, go-xmlstruct consists of two phases:

  1. Firstly, go-xmlstruct explores all input XML documents to determine their structure. It gathers statistics on the types used for each attribute, chardata, and child element.
  2. Secondly, go-xmlstruct generates a Go struct based on the observed structure using the gathered statistics to determine the type of each field.

License

MIT

Documentation

Overview

Package xmlstruct generates Go structs from multiple XML documents.

Index

Constants

View Source
const (
	DefaultCharDataFieldName            = "CharData"
	DefaultFormatSource                 = true
	DefaultHeader                       = "// This file is automatically generated. DO NOT EDIT."
	DefaultTopLevelAttributes           = false
	DefaultIntType                      = "int"
	DefaultNamedTypes                   = false
	DefaultPackageName                  = "main"
	DefaultPreserveOrder                = false
	DefaultTimeLayout                   = "2006-01-02T15:04:05Z"
	DefaultUsePointersForOptionalFields = true
	DefaultUseRawToken                  = false
)

Variables

View Source
var (
	SkipDir = fs.SkipDir
	//lint:ignore ST1012 SkipFile is not an error
	SkipFile = errors.New("skip file") //nolint:errname
)
View Source
var (
	// TitleFirstRuneExportNameFunc returns name.Local with the initial rune
	// capitalized.
	TitleFirstRuneExportNameFunc = func(name xml.Name) string {
		runes := []rune(name.Local)
		runes[0] = unicode.ToUpper(runes[0])
		return string(runes)
	}

	// DefaultExportNameFunc returns name.Local with kebab- and snakecase words
	// converted to camelcase and any Id suffix converted to ID.
	DefaultExportNameFunc = func(name xml.Name) string {
		localName := kebabOrSnakeCaseWordBoundaryRx.ReplaceAllStringFunc(name.Local, func(s string) string {
			return strings.ToUpper(s[len(s)-1:])
		})
		localName = nonIdentifierRuneRx.ReplaceAllLiteralString(localName, "")
		runes := []rune(localName)
		runes[0] = unicode.ToUpper(runes[0])
		if len(runes) > 1 && runes[len(runes)-2] == 'I' && runes[len(runes)-1] == 'd' {
			runes[len(runes)-1] = 'D'
		}
		return string(runes)
	}
)
View Source
var (
	// IgnoreNamespaceNameFunc returns name with name.Space cleared. The same
	// local name in different namespaces will be treated as identical names.
	IgnoreNamespaceNameFunc = func(name xml.Name) xml.Name {
		return xml.Name{
			Local: name.Local,
		}
	}

	// The IdentityNameFunc returns name unchanged. The same local name in
	// different namespaces will be treated as distinct names.
	IdentityNameFunc = func(name xml.Name) xml.Name {
		return name
	}

	DefaultNameFunc = IgnoreNamespaceNameFunc
)

Functions

This section is empty.

Types

type ExportNameFunc

type ExportNameFunc func(xml.Name) string

An ExportNameFunc returns the exported Go identifier for the given xml.Name.

type Generator

type Generator struct {
	// contains filtered or unexported fields
}

A Generator observes XML documents and generates Go structs into which the XML documents can be unmarshalled.

func NewGenerator

func NewGenerator(options ...GeneratorOption) *Generator

NewGenerator returns a new Generator with the given options.

func (*Generator) Generate

func (g *Generator) Generate() ([]byte, error)

Generate returns the generated Go source for all the XML documents observed so far.

func (*Generator) ObserveFS

func (g *Generator) ObserveFS(fsys fs.FS, root string, observeFunc func(string, fs.DirEntry, error) error) error

ObserveFS observes all XML documents in fs.

func (*Generator) ObserveFile

func (g *Generator) ObserveFile(name string) error

ObserveFile observes an XML document in the given file.

func (*Generator) ObserveReader

func (g *Generator) ObserveReader(r io.Reader) error

ObserveReader observes an XML document from r.

type GeneratorOption

type GeneratorOption func(*Generator)

A GeneratorOption sets an option on a Generator.

func WithCharDataFieldName

func WithCharDataFieldName(charDataFieldName string) GeneratorOption

WithCharDataFieldName sets the char data field name.

func WithExportNameFunc

func WithExportNameFunc(exportNameFunc ExportNameFunc) GeneratorOption

WithExportNameFunc sets the export name function for the generated Go source.

func WithExportRenames

func WithExportRenames(exportRenames map[string]string) GeneratorOption

WithExportRenames sets the export renames.

func WithFormatSource

func WithFormatSource(formatSource bool) GeneratorOption

WithFormatSource sets whether to format the generated Go source.

func WithHeader

func WithHeader(header string) GeneratorOption

WithHeader sets the header of the generated Go source.

func WithIntType

func WithIntType(intType string) GeneratorOption

WithIntType sets the int type in the generated Go source.

func WithNameFunc

func WithNameFunc(nameFunc NameFunc) GeneratorOption

WithNameFunc sets the name function.

func WithNamedTypes

func WithNamedTypes(namedTypes bool) GeneratorOption

WithNamedTypes sets whether all to generate named types for all elements.

func WithPackageName

func WithPackageName(packageName string) GeneratorOption

WithPackageName sets the package name of the generated Go source.

func WithPreserveOrder

func WithPreserveOrder(preserveOrder bool) GeneratorOption

WithPreserveOrder sets whether to preserve the order of types and fields.

func WithTimeLayout

func WithTimeLayout(timeLayout string) GeneratorOption

WithTimeLayout sets the time layout used to identify times in the observed XML documents. Use an empty string to disable identifying times.

func WithTopLevelAttributes

func WithTopLevelAttributes(topLevelAttributes bool) GeneratorOption

WithTopLevelAttributes sets whether to include top level attributes.

func WithUsePointersForOptionalFields

func WithUsePointersForOptionalFields(usePointersForOptionalFields bool) GeneratorOption

WithUsePointersForOptionFields sets whether to use pointers for optional fields in the generated Go source.

func WithUseRawToken

func WithUseRawToken(useRawToken bool) GeneratorOption

WithUseRawToken sets whether to use encoding/xml.Decoder.Token or encoding/xml.Decoder.RawToken.

type NameFunc

type NameFunc func(xml.Name) xml.Name

A NameFunc modifies xml.Names observed in the XML documents.

Directories

Path Synopsis
cmd
goxmlstruct
Command xmlstruct generates Go structs from multiple XML documents.
Command xmlstruct generates Go structs from multiple XML documents.
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL