在Golang中将XML转换为JSON。

huangapple go评论67阅读模式
英文:

Converting xml to json in Golang

问题

我正在使用github.com/basgys/goxml2json进行XML到JSON的转换。以下是示例代码:

package main

import (
	"fmt"
	"strings"
	xj "github.com/basgys/goxml2json"
)

func main() {
	xml := strings.NewReader(`<?xml version="1.0" encoding="UTF-8"?>
	<osm version="0.6" generator="CGImap 0.0.2">
		<bounds minlat="54.0889580" minlon="12.2487570" maxlat="54.0913900" maxlon="12.2524800"/>
		<foo>bar</foo>
	</osm>`)

	json, err := xj.Convert(xml)
	if err != nil {
		panic("ERROR converting xml to json")
	}

	fmt.Println(json.String())
}

上述代码的输出结果为:

{
  "osm": {
    "-version": 0.6,
    "-generator": "CGImap 0.0.2",
    "bounds": {
      "-minlat": "54.0889580",
      "-minlon": "12.2487570",
      "-maxlat": "54.0913900",
      "-maxlon": "12.2524800"
    },
    "foo": "bar"
  }
}

然而,我期望的输出结果如下所示,与https://codebeautify.org/xmltojson/y2221f265给出的结果相同:

{
  "osm": {
    "bounds": "",
    "foo": "bar"
  }
}

如何从JSON输出中删除以-开头的键?我事先不知道数据的结构。

英文:

I'm using github.com/basgys/goxml2json for xml to json conversion. Below is the example code:

package main

import (
	&quot;fmt&quot;
	&quot;strings&quot;
	xj &quot;github.com/basgys/goxml2json&quot;
)

func main() {
	xml := strings.NewReader(`&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
	&lt;osm version=&quot;0.6&quot; generator=&quot;CGImap 0.0.2&quot;&gt;
	 &lt;bounds minlat=&quot;54.0889580&quot; minlon=&quot;12.2487570&quot; maxlat=&quot;54.0913900&quot; maxlon=&quot;12.2524800&quot;/&gt;
	 &lt;foo&gt;bar&lt;/foo&gt;
	&lt;/osm&gt;`)

	json, err := xj.Convert(xml)
	if err != nil {
		panic(&quot;ERROR converting xml to json&quot;)
	}

	fmt.Println(json.String())
}

The output of the above code is:

  {
    &quot;osm&quot;: {
      &quot;-version&quot;: 0.6,
      &quot;-generator&quot;: &quot;CGImap 0.0.2&quot;,
      &quot;bounds&quot;: {
        &quot;-minlat&quot;: &quot;54.0889580&quot;,
        &quot;-minlon&quot;: &quot;12.2487570&quot;,
        &quot;-maxlat&quot;: &quot;54.0913900&quot;,
        &quot;-maxlon&quot;: &quot;12.2524800&quot;
      },
      &quot;foo&quot;: &quot;bar&quot;
    }
  }

However, I am expecting the output like below as given by https://codebeautify.org/xmltojson/y2221f265:

{
  &quot;osm&quot;: {
    &quot;bounds&quot;: &quot;&quot;,
    &quot;foo&quot;: &quot;bar&quot;
  }
}

How to remove the keys starting with - from the JSON output? I do not know the structure of the data beforehand.

答案1

得分: 2

我认为这应该可以。这是goxml2json.Convert函数的修改版本。使用WithAttrPrefix来指定一个自定义前缀(以防你想在正文开头使用-)。

请注意,这仅适用于主分支上的最新提交,v1.1.0标签不支持插件,所以你必须像这样获取它:go get github.com/basgys/goxml2json@master

RemoveAttr函数递归删除所有具有给定前缀的子节点。你也可以在此时进行其他修改。

package main

import (
	"bytes"
	"fmt"
	"strings"

	xj "github.com/basgys/goxml2json"
)

const prefix = "veryuniqueattrprefix-"

func main() {
	xml := strings.NewReader(`<?xml version="1.0" encoding="UTF-8"?>
    <osm version="0.6" generator="CGImap 0.0.2">
     <bounds minlat="54.0889580" minlon="12.2487570" maxlat="54.0913900" maxlon="12.2524800"/>
     <foo>bar</foo>
    </osm>`)

	// 解码XML文档
	root := &xj.Node{}
	err := xj.NewDecoder(
		xml,
		xj.WithAttrPrefix(prefix),
	).Decode(root)
	if err != nil {
		panic(err)
	}

	RemoveAttr(root)

	// 然后将其编码为JSON
	buf := new(bytes.Buffer)
	e := xj.NewEncoder(buf)
	err = e.Encode(root)
	if err != nil {
		panic(err)
	}

	fmt.Println(buf.String())
}

func RemoveAttr(n *xj.Node) {
	for k, v := range n.Children {
		if strings.HasPrefix(k, prefix) {
			delete(n.Children, k)
		} else {
			for _, n := range v {
				RemoveAttr(n)
			}
		}
	}
}

输出结果为:

{"osm": {"bounds": "", "foo": "bar"}}
英文:

I think this should do it. It is a modified version of the goxml2json.Convert func. Used the WithAttrPrefix to specify a custom prefix(in case you ever want to use a - at the start of your body).

Please note that this only works for the latest commit on the master branch, the v1.1.0 tag doesn't support plugins, so you have to go get it like so: go get github.com/basgys/goxml2json@master

RemoveAttr just recursively deletes all children with the given prefix. You could also do other modifications at this point.

package main

import (
	&quot;bytes&quot;
	&quot;fmt&quot;
	&quot;strings&quot;

	xj &quot;github.com/basgys/goxml2json&quot;
)

const prefix = &quot;veryuniqueattrprefix-&quot;

func main() {
	xml := strings.NewReader(`&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
    &lt;osm version=&quot;0.6&quot; generator=&quot;CGImap 0.0.2&quot;&gt;
     &lt;bounds minlat=&quot;54.0889580&quot; minlon=&quot;12.2487570&quot; maxlat=&quot;54.0913900&quot; maxlon=&quot;12.2524800&quot;/&gt;
     &lt;foo&gt;bar&lt;/foo&gt;
    &lt;/osm&gt;`)

	// Decode XML document
	root := &amp;xj.Node{}
	err := xj.NewDecoder(
		xml,
		xj.WithAttrPrefix(prefix),
	).Decode(root)
	if err != nil {
		panic(err)
	}

	RemoveAttr(root)

	// Then encode it in JSON
	buf := new(bytes.Buffer)
	e := xj.NewEncoder(buf)
	err = e.Encode(root)
	if err != nil {
		panic(err)
	}

	fmt.Println(buf.String())
}

func RemoveAttr(n *xj.Node) {
	for k, v := range n.Children {
		if strings.HasPrefix(k, prefix) {
			delete(n.Children, k)
		} else {
			for _, n := range v {
				RemoveAttr(n)
			}
		}
	}
}

outputs:

{&quot;osm&quot;: {&quot;bounds&quot;: &quot;&quot;, &quot;foo&quot;: &quot;bar&quot;}}

答案2

得分: 1

请稍等,我会为您翻译这段代码。

英文:

Try this

package main
import (
&quot;encoding/json&quot;
&quot;fmt&quot;
&quot;strings&quot;
xj &quot;github.com/basgys/goxml2json&quot;
)
// ToObject - convert string to any given struct
func ToObject(value string, object interface{}) error {
err := json.Unmarshal([]byte(value), &amp;object)
if err != nil {
return err
}
return nil
}
func main() {
xml := strings.NewReader(`&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;osm version=&quot;0.6&quot; generator=&quot;CGImap 0.0.2&quot;&gt;
&lt;bounds minlat=&quot;54.0889580&quot; minlon=&quot;12.2487570&quot; maxlat=&quot;54.0913900&quot; maxlon=&quot;12.2524800&quot;/&gt;
&lt;foo&gt;bar&lt;/foo&gt;
&lt;/osm&gt;`)
converter, err := xj.Convert(xml)
if err != nil {
panic(&quot;ERROR converting xml to json&quot;)
}
osmStruct := &amp;ExampleStruct{}
ToObject(converter.String(), &amp;osmStruct)
b, _ := json.Marshal(osmStruct)
fmt.Println(string(b))
}
// ExampleStruct -
type ExampleStruct struct {
Osm Osm `json:&quot;osm&quot;`
}
// Osm -
type Osm struct {
Version   string `json:&quot;,omitempty&quot;`
Generator string `json:&quot;,omitempty&quot;`
Bounds    Bounds `json:&quot;bounds&quot;`
Foo       string `json:&quot;foo&quot;`
}
// Bounds -
type Bounds struct {
Minlat string `json:&quot;,omitempty&quot;`
Minlon string `json:&quot;,omitempty&quot;`
Maxlat string `json:&quot;,omitempty&quot;`
Maxlon string `json:&quot;,omitempty&quot;`
}

huangapple
  • 本文由 发表于 2022年4月14日 15:09:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/71867711.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定