
Security News
Open Source Maintainers Demand Ability to Block Copilot-Generated Issues and PRs
Open source maintainers are urging GitHub to let them block Copilot from submitting AI-generated issues and pull requests to their repositories.
github.com/clbanning/mxj/v2
mxj supplants the legacy x2j and j2x packages. If you want the old syntax, use mxj/x2j and mxj/j2x packages.
go get github.com/clbanning/mxj/v2@v2.7
import "github.com/clbanning/mxj/v2"
... or just vendor the package.
https://github.com/clbanning/checkxml provides functions for validating XML data.
Nodes m.XML() time
54809 12.53708ms
109780 32.403183ms
164678 59.826412ms
482598 109.358007ms
BenchmarkNewMapXml-4 100000 18043 ns/op
BenchmarkNewStructXml-4 100000 14892 ns/op
BenchmarkNewMapJson-4 300000 4633 ns/op
BenchmarkNewStructJson-4 300000 3427 ns/op
BenchmarkNewMapXmlBooks-4 20000 82850 ns/op
BenchmarkNewStructXmlBooks-4 20000 67822 ns/op
BenchmarkNewMapJsonBooks-4 100000 17222 ns/op
BenchmarkNewStructJsonBooks-4 100000 15309 ns/op
2022.11.28: v2.7 - add SetGlobalKeyMapPrefix to change default prefix, '#', for default keys
2022.11.20: v2.6 - add NewMapForattedXmlSeq for XML docs formatted with whitespace character
2021.02.02: v2.5 - add XmlCheckIsValid toggle to force checking that the encoded XML is valid
2020.12.14: v2.4 - add XMLEscapeCharsDecoder to preserve XML escaped characters in Map values
2020.10.28: v2.3 - add TrimWhiteSpace option
2020.05.01: v2.2 - optimize map to XML encoding for large XML docs.
2019.07.04: v2.0 - remove unnecessary methods - mv.XmlWriterRaw, mv.XmlIndentWriterRaw - for Map and MapSeq.
2019.07.04: Add MapSeq type and move associated functions and methods from Map to MapSeq.
2019.01.21: DecodeSimpleValuesAsMap - decode to map[<tag>:map["#text":<value>]] rather than map[<tag>:<value>]
2018.04.18: mv.Xml/mv.XmlIndent encodes non-map[string]interface{} map values - map[string]string, map[int]uint, etc.
2018.03.29: mv.Gob/NewMapGob support gob encoding/decoding of Maps.
2018.03.26: Added mxj/x2j-wrapper sub-package for migrating from legacy x2j package.
2017.02.22: LeafNode paths can use ".N" syntax rather than "[N]" for list member indexing.
2017.02.10: SetFieldSeparator changes field separator for args in UpdateValuesForPath, ValuesFor... methods.
2017.02.06: Support XMPP stream processing - HandleXMPPStreamTag().
2016.11.07: Preserve name space prefix syntax in XmlSeq parser - NewMapXmlSeq(), etc.
2016.06.25: Support overriding default XML attribute prefix, "-", in Map keys - SetAttrPrefix().
2016.05.26: Support customization of xml.Decoder by exposing CustomDecoder variable.
2016.03.19: Escape invalid chars when encoding XML attribute and element values - XMLEscapeChars().
2016.03.02: By default decoding XML with float64 and bool value casting will not cast "NaN", "Inf", and "-Inf".
To cast them to float64, first set flag with CastNanInf(true).
2016.02.22: New mv.Root(), mv.Elements(), mv.Attributes methods let you examine XML document structure.
2016.02.16: Add CoerceKeysToLower() option to handle tags with mixed capitalization.
2016.02.12: Seek for first xml.StartElement token; only return error if io.EOF is reached first (handles BOM).
2015.12.02: XML decoding/encoding that preserves original structure of document. See NewMapXmlSeq()
and mv.XmlSeq() / mv.XmlSeqIndent().
2015-05-20: New: mv.StringIndentNoTypeInfo().
Also, alphabetically sort map[string]interface{} values by key to prettify output for mv.Xml(),
mv.XmlIndent(), mv.StringIndent(), mv.StringIndentNoTypeInfo().
2014-11-09: IncludeTagSeqNum() adds "_seq" key with XML doc positional information.
(NOTE: PreserveXmlList() is similar and will be here soon.)
2014-09-18: inspired by NYTimes fork, added PrependAttrWithHyphen() to allow stripping hyphen from attribute tag.
2014-08-02: AnyXml() and AnyXmlIndent() will try to marshal arbitrary values to XML.
2014-04-28: ValuesForPath() and NewMap() now accept path with indexed array references.
type Map map[string]interface{}
Create a Map
value, 'mv', from any map[string]interface{}
value, 'v':
mv := Map(v)
Unmarshal / marshal XML as a Map
value, 'mv':
mv, err := NewMapXml(xmlValue) // unmarshal xmlValue, err := mv.Xml() // marshal
Unmarshal XML from an io.Reader
as a Map
value, 'mv':
mv, err := NewMapXmlReader(xmlReader) // repeated calls, as with an os.File Reader, will process stream mv, raw, err := NewMapXmlReaderRaw(xmlReader) // 'raw' is the raw XML that was decoded
Marshal Map
value, 'mv', to an XML Writer (io.Writer
):
err := mv.XmlWriter(xmlWriter) raw, err := mv.XmlWriterRaw(xmlWriter) // 'raw' is the raw XML that was written on xmlWriter
Also, for prettified output:
xmlValue, err := mv.XmlIndent(prefix, indent, ...) err := mv.XmlIndentWriter(xmlWriter, prefix, indent, ...) raw, err := mv.XmlIndentWriterRaw(xmlWriter, prefix, indent, ...)
Bulk process XML with error handling (note: handlers must return a boolean value):
err := HandleXmlReader(xmlReader, mapHandler(Map), errHandler(error)) err := HandleXmlReaderRaw(xmlReader, mapHandler(Map, []byte), errHandler(error, []byte))
Converting XML to JSON: see Examples for NewMapXml
and HandleXmlReader
.
There are comparable functions and methods for JSON processing.
Arbitrary structure values can be decoded to / encoded from Map
values:
mv, err := NewMapStruct(structVal) err := mv.Struct(structPointer)
paths := mv.PathsForKey(key) path := mv.PathForKeyShortest(key) values, err := mv.ValuesForKey(key, subkeys) values, err := mv.ValuesForPath(path, subkeys) count, err := mv.UpdateValuesForPath(newVal, path, subkeys)
Get everything at once, irrespective of path depth:
leafnodes := mv.LeafNodes() leafvalues := mv.LeafValues()
A new Map
with whatever keys are desired can be created from the current Map
and then encoded in XML
or JSON. (Note: keys can use dot-notation.)
newMap, err := mv.NewMap("oldKey_1:newKey_1", "oldKey_2:newKey_2", ..., "oldKey_N:newKey_N") newMap, err := mv.NewMap("oldKey1", "oldKey3", "oldKey5") // a subset of 'mv'; see "examples/partial.go" newXml, err := newMap.Xml() // for example newJson, err := newMap.Json() // ditto
The package is fairly well self-documented with examples.
Also, the subdirectory "examples" contains a wide range of examples, several taken from golang-nuts discussions.
Using NewMapXml()
map[string]interface{}
values by prefixing a hyphen, -
,
to the attribute label. (Unless overridden by PrependAttrWithHyphen(false)
or
SetAttrPrefix()
.)#text
for its map[string]interface{}
representation. (See
the 'atomFeedString.xml' test data, below.)Using NewMapXmlSeq()
map["#attr"]map[<attr_label>]map[string]interface{}
values
where the <attr_label>
value has "#text" and "#seq" keys - the "#text" key holds the
value for <attr_label>
.<ns:key>something</ns.key>
parses to map["ns:key"]interface{}{"something"}
xmlns:ns="http://myns.com/ns"
parses to map["xmlns:ns"]interface{}{"http://myns.com/ns"}
Both
Map
values, which may represent 'null' JSON values, are encoded as <tag/>
.
NOTE: the operation is not symmetric as <tag/>
elements are decoded as tag:""
Map
values,
which, then, encode in JSON as "tag":""
values.Because there are no guarantees on the sequence map elements are retrieved, the tests have been written for visual verification in most cases. One advantage is that you can easily use the output from running "go test" as examples of calling the various functions and methods.
I make extensive use of JSON for messaging and typically unmarshal the messages into
map[string]interface{}
values. This is easily done using json.Unmarshal
from the
standard Go libraries. Unfortunately, many legacy solutions use structured
XML messages; in those environments the applications would have to be refactored to
interoperate with my components.
The better solution is to just provide an alternative HTTP handler that receives
XML messages and parses it into a map[string]interface{}
value and then reuse
all the JSON-based code. The Go xml.Unmarshal()
function does not provide the same
option of unmarshaling XML messages into map[string]interface{}
values. So I wrote
a couple of small functions to fill this gap and released them as the x2j package.
Over the next year and a half additional features were added, and the companion j2x
package was released to address XML encoding of arbitrary JSON and map[string]interface{}
values. As part of a refactoring of our production system and looking at how we had been
using the x2j and j2x packages we found that we rarely performed direct XML-to-JSON or
JSON-to_XML conversion and that working with the XML or JSON as map[string]interface{}
values was the primary value. Thus, everything was refactored into the mxj package.
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Open source maintainers are urging GitHub to let them block Copilot from submitting AI-generated issues and pull requests to their repositories.
Research
Security News
Malicious Koishi plugin silently exfiltrates messages with hex strings to a hardcoded QQ account, exposing secrets in chatbots across platforms.
Research
Security News
Malicious PyPI checkers validate stolen emails against TikTok and Instagram APIs, enabling targeted account attacks and dark web credential sales.