• This repository has been archived on 23/Jun/2024
  • Stars
    star
    215
  • Rank 183,393 (Top 4 %)
  • Language
    Go
  • License
    MIT License
  • Created almost 12 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

[stable since 2013] a lib for loading XML Schema Definition (XSD) files ➜ plus, a tool `makepkg` to code-generate from any *.xsd your Go package with all needed `struct`s to readily `xml.Unmarshal()` documents into, based on the XSD's schema definitions. NOT REALLY MAINTAINED FOR YEARS NOW: try the forks if running into issues.

go-xsd

A Go package for loading ( xml.Unmarshal()-ing ) an XML Schema Definition (XSD) document into an xsd.Schema structure.

With this, you could probably write an XML validator, or otherwise utilize or further process the loaded XSD --- but the main use-case here was:

go-xsd/xsd-makepkg

A command-line tool to generate Go "XML wrapper" package sources for specified XSD schema URIs.

If no arguments are specified, this tool proceeds to (re)generate all Go packages for various common XML formats in your local $GOPATH-relative directory corresponding to the http://github.com/metaleap/go-xsd-pkg repository. For more details on command-line arguments for xsd-makepkg: scroll down to the bottom of this readme.

Each generated wrapper package contains the type structures required to easily xml.Unmarshal() an XML document based on that XSD.

XSD simple-types are represented by the corresponding native Go scalar data type, augmented by utility methods where applicable:

  • enumerated simple-types (eg. "value can be 'sunny', 'cloudy', 'rainy'") get handy corresponding IsXyz() bool methods (eg. "IsSunny()", "IsCloudy()", "IsRainy()")

  • simple-types that define a whitespace-separated list of scalar values get a corresponding, properly typed Values() method

  • for attributes or elements that define a fixed or default value, their corresponding generated Go simple-type will have a properly typed ElemnameDefault() / ElemnameFixed() / AttnameDefault() / AttnameFixed() method (eg. if the langpref attribute is defined to default to "Go", then its simple-type will have a LangprefDefault() method returning "Go")

XSD complex-types, attribute-groups, element-groups, elements etc. are ultimately represented by corresponding generated Go struct types.

XSD includes are all loaded and processed together into a single output .go source file.

XSD imports are rewritten as Go imports but not otherwise auto-magically processed. If you see the generated .go package importing another "some-xsd-xml-whatever-name-_go" package that will cause a "package not found" compiler error, then to make that import work, you'll first need to also auto-generate that package with xsd-makepkg yourself as well.

XSD documentation annotation is rewritten as Go // code comments. Yeah, that's rather neat.

Regarding the auto-generated code:

  • it's by necessity not idiomatic and most likely not as terse/slim as manually-written structs would be. For very simplistic XML formats, writing your own 3 or 4 custom structs might be a tiny bit more efficient. For highly intricate, unwieldy XML formats, the auto-generated packages beat hand-writing 100s of custom structs, however. Auto-generated code will never win a code-beauty contest, you're expected to simply import the compiled package rather than having to work inside its generated source files.

  • most (XSD-declared) types are prefixed with T -- thanks to the SVG schema which taught me that in XSD, "scriptType" and "ScriptType" are two valid and uniquely different type names. To have all types exported from the generated Go package, then, some kind of prefix is indeed needed.

  • most XSDs are chock-full of anonymous types, as well as implicit ones (unions, restrictions, extensions...) Go does support "anonymous types" per se, but I decided against using them. Every type is declared and exported, no anonymous magic. This makes most auto-generated packages "look" even more confusing than their XSD counterparts at first glance. Indeed they may appear quite bloated, and when coding with the imported generated package you'll probably be better off working with the particular XML format's specification document rather than the godoc for the generated package... this is not a perfect situation but at least for now I can work with this for the few XML formats I occasionally need to "parse, convert and forget" -- ultimately, most XML formats at my end are mere interchange or legacy formats, and never really the "main topic" at hand.

go-xsd/types

A tiny package automatically imported by all go-xsd auto-generated packages. Maps all XSD built-in simple-types to Go types, which affords us easy mapping of any XSD type references in the schema to Go imports: every xs:string and xs:boolean automatically becomes xsdt.String and xsdt.Boolean etc. Types are mapped to Go types depending on how encoding/xml.Unmarshal() can handle them: ie. it parses bools and numbers, but dates/durations have too many format mismatches and thus are just declared string types. Same for base64- and hex-encoded binary data: since Unmarshal() won't decode them, we leave them as strings. If you need their binary data, your code needs to import Go's base64/hex codec packages and use them as necessary.

How to use auto-generated packages:

Take a look at the "test progs" under xsd-makepkg/tests, they're basically simple usage examples. For unmarshal you need to define just one small custom struct like this --- using the rss package as a simple example, as demonstrated in xsd-makepkg/tests/xsd-test-rss/main.go:

type MyRssDoc struct {
    XMLName xml.Name `xml:"rss"`
    rss.TxsdRss
}

So your custom struct specifies two things:

  • the XML name of the root element in your XML file, as is typical when working with encoding/xml.Unmarshal().

  • the Go struct type from the auto-generated package to embed right inside your custom struct.

The second part is the only tricky part. XML Schema Definition has no real concept of "root element", partly because they're designed to support use-cases where you embed a full document defined in one XSD deep inside a full document defined in another XSD. So a Collada document may contain a full or partial MathML document somewhere inside it. Some well-designed XSDs define a single top-level element, so we could infer "this is the root element" and generate a "XyzDoc" struct (like the MyRssDoc above) for you. But many don't. Some formats may legally have one of two or more possible "root" elements, ie. Atom allegedly may have either a "feed" root element or an "entry" root element. So go-xsd does not magically infer which of the XSD's top-level elements might be the root element, you define this by writing a small struct as shown above. The naming of the root element Go type to be embedded is not consistent across different packages, because their naming is directly based on the XSD that was used to generate the package. So for example...

  • for rss we have rss.TxsdRss
  • for atom: atom.TentryType and atom.TfeedType
  • for svg: svg.TsvgType
  • for Collada: collada.TxsdCollada

Seems like Collada and RSS share a certain naming pattern, and yet Atom/SVG share another one? Mere coincidence, the naming is completely arbitrary and up to the XSD author. Ultimately, to find out the proper Go type name to embed, you'll have to dig a bit inside the generated package. That's actually pretty straightforward, here's how you do it:

A) Suppose you have an XML format where the root element (and only that one) is known to be named:

<gopher>

B) Open the generated Go package source files under $GOPATH/src/github.com/metaleap/go-xsd-pkg/yourdomain.org/xsd/gopher.xsd_go/*.go (unless you used custom paths when you ran the go-xsd/xsd-makepkg tool)

C) Search for an occurence of either:

"gopher"`

( quote, gopher, quote, backtick ), or:

 gopher"`

( whitespace, gopher, quote, backtick )

D) The found occurence is likely the tag for a field in a type named something like XsdGoPkgHasElem_Gopher or XsdGoPkgHasElems_Gopher. Ignore that type, instead focus on the type of the field itself. That's the one you're looking for, the one to embed in your tiny custom doc struct.

Command-line flags for go-xsd/xsd-makepkg tool:

  • -basepath="": Defaults to github.com/metaleap/go-xsd-pkg. A $GOPATH/src/-relative path (always a slash-style path, even on Windows) where XSD files are downloaded to / loaded from and generated Go wrapper packages are created. Any XSD imports are also rewritten as Go imports from that path (but are not otherwise auto-magically processed in any way).
  • -local=true: Local copy -- only downloads if file does not exist locally
  • -parse=false: Not necessary, unless the generated Go wrapper package fails to compile with either the error "cannot convert {value} to type {type}" or "cannot use {value} (type {type}) as type {type} in return argument" -- ultimately down to a slightly faulty XSD file, but while rare, those exist (hello, KML using 0 and 1 for xs:booleans that are clearly spec'd to be only ever either true or false...)
  • -uri="": The XML Schema Definition file URIs to generate a Go wrapper packages from, whitespace-separated. (For each, the protocol prefix can be omitted, it then defaults to http://. Only protocols understood by the net/http package are supported.)
  • -gofmt=true: Run 'gofmt' against the generated Go wrapper package?
  • -goinst=true: Run 'go-buildrun' ( http://github.com/metaleap/go-buildrun ) against the generated Go wrapper package?

More Repositories

1

go-ngine

[2013, incomplete] the goal back then: "a Go-native, modern-OpenGL real-time 3D rendering engine" ➜ I think it's still a solid *basis* for one; the real "meat" is in `___old2013` ➜ project stalled out as my focus shifted elsewhere from 2014
Go
77
star
2

go-leansite

[2013] a most minimalistic "dynamic-web-page" server written in Go (exploring the `net/http`, `html/template`, and Gorilla libs) ➜ both standalone or on AppEngine (served metaleap.net 2013 - 2016)
Go
32
star
3

go-opengl

[stable since 2013] lib for creating OpenGL apps of the cross-platform and modern sort (ie. Core profile 3.3+, shader-based, no display lists etc)
Go
20
star
4

go-fromjsonschema

[2017-2018, maintained, stable] generates Go type definitions (ready to `json.Unmarshal` into) from a JSON Schema definition (proper JSD, not just sample .json) file
Go
20
star
5

go-xsd-pkg

[2013] wrappers for various common XML formats, ready for use with `encoding/xml.Unmarshal()`, all generated with my `go-xsd` project
Go
17
star
6

go-fsdb

[2013] for prototyping data-access layers: a mock "DB driver" (compatible with `database/sql`) using a local directory of (json/toml) files as a backing "database" of "tables" (no query language =)
Go
16
star
7

go-collada

[2013] libs for the Collada 3D content open-standard file format
Go
13
star
8

haxtatic

[2017, stable] static site generator focusing on: raw performance ➜ powerful out-of-box building blocks ➜ composable no-nonsense-time-saver features ➜ dead-simple extensibility (for Haskell hackers) ➜ detailed & ~99% complete docs
Haskell
9
star
9

go-util

[stable but abandoned β€” new under github.com/go-leap] 3d, db, db/mgo, dev, dev/bower, dev/go, dev/hs, dev/ps, fs, geo, gfx, hash, net, num, run, slice, str, sys
Go
7
star
10

go-buildrun

[2013; outdated/abandoned] simple-minded "build tool" that performs "pseudo-generics templating" Go code generation just prior to then invoking `go install` and running the result if package is an executable (`package main`)
Go
7
star
11

zui

[WIP] Svelte clone in Go
Go
6
star
12

rosetta-haskell-dump

Haskell-only sources from rosettacode.org -- useful when writing language-level tooling -- copied from acmeism/RosettaCodeData
Haskell
4
star
13

zentient

[2017-2019, maintained, stable; great for Go, meagre for others] multi-language, multi-editor IDE backend (frontends in separate repos) ➜ first iteration: language support for Go (fully) & Haskell (minimally) ➜ front-ends: for the VScode and Textadept editors (in `zentient-vscode` & `zentient-textadept` repos)
Go
4
star
14

gonad-coreimp

[2017, incomplete & aborted] PureScript-to-Golang exploration (alternative to gonad-corefn)
Go
3
star
15

vscode-extexpo

[2017] showcases most-all kinds of integrations possible in a custom VScode extension
TypeScript
3
star
16

textadept-stuff

Scripts and customizations for the lean+mean+clean `foicica.com/textadept` editor
Lua
2
star
17

go-geo-names

[ca. 2011 β€” pre Go 1.0] fetch-parse-and-mongodb raw `download.GeoNames.org/export/dump` CSV data files
Go
1
star
18

go-machines

[2018 - 2019, exploratory Β· demo Β· edu] state-transition machines / byte-code VMs + graph-reducing evaluators / etc.
Go
1
star
19

mzprobs

MiniZinc: various real-worldish (not-too-mathy/puzzly) problem formulations
1
star
20

gonad-corefn

[2017, incomplete & aborted] PureScript-to-Golang exploration (alternative to gonad-coreimp)
Go
1
star
21

haxpile-apptests

[2017, aborted] complementary to haxpile
Haskell
1
star
22

go-ezmq

[2017] Higher-level, type-driven, simplified message-queuing ➜ wrapping+hiding+streamlining RabbitMQ-via-streadway/amqp under the hood
Go
1
star
23

zentient-vscode

[2017-2019, maintained, stable] `zentient` frontend (in Node.js TypeScript) for VS-Code
TypeScript
1
star