Gox语言中如何处理XML-GX20

Gox语言中集成了Go语言的第三方库etree,因此已经内置XML文档的处理功能。etree更详细的文档可参考这里

我们直接来看下面这个例子:

etree = github_beevik_etree

reshapeXMLX = fn(xmlA) {
	treeT = etree.NewDocument()

	if treeT == nil {
		return tk.GenerateErrorStringF("create XML tree failed")
	}

	errT = treeT.ReadFromString(xmlA)

	if errT != nil {
		return tk.GenerateErrorStringF("invalid XML: %v", errT)
	}

	treeT.Indent(2)

	outputT, errT = treeT.WriteToString()

	if errT != nil {
		return tk.GenerateErrorStringF("failed to reshape XML: %v", errT)
	}

	return outputT

}

flattenXML = fn(xmlA, nodeA) {
	treeT = etree.NewDocument()

	if treeT == nil {
		return tk.GenerateErrorStringF("create XML tree failed")
	}

	errT = treeT.ReadFromString(xmlA)

	if errT != nil {
		return tk.GenerateErrorStringF("invalid XML: %v", errT)
	}

	rootNodeT = treeT.FindElement("//" + nodeA)

	if rootNodeT == nil {
		return tk.GenerateErrorStringF("node not found: %v", nodeA)
	}

	nodesT = rootNodeT.ChildElements()

	bufT = new(strings.Builder)

	for i, v = range nodesT {
		if i > 0 {
			bufT.WriteString("\n")
		}

		bufT.WriteString(tk.Spr("%v: %v", v.Tag, v.Text()))
	}

	return bufT.String()

}

getMSSFromXML = fn(xmlA, nodeA) {
	treeT = etree.NewDocument()

	if treeT == nil {
		return nil, tk.Errf("create XML tree failed")
	}

	errT = treeT.ReadFromString(xmlA)

	if errT != nil {
		return nil, tk.Errf("invalid XML: %v", errT)
	}

	rootNodeT = treeT.FindElement("//" + nodeA)

	if rootNodeT == nil {
		return nil, tk.Errf("node not found: %v", nodeA)
	}

	nodesT = rootNodeT.ChildElements()

	mapT = make(map[string]string, len(nodesT))
	for _, jv = range nodesT {
		mapT[jv.Tag] = jv.Text()
	}

	return mapT, nil
}

getMSSArrayFromXML = fn(xmlA, nodeA) {
	treeT = etree.NewDocument()

	if treeT == nil {
		return nil, tk.Errf("create XML tree failed")
	}

	errT = treeT.ReadFromString(xmlA)

	if errT != nil {
		return nil, tk.Errf("invalid XML: %v", errT)
	}

	rootNodeT = treeT.FindElement("//" + nodeA)

	if rootNodeT == nil {
		return nil, tk.Errf("node not found: %v", nodeA)
	}

	nodesT = rootNodeT.ChildElements()

	aryT = make([]map[string]string, 0)

	for _, v = range nodesT {
		internalNodesT = v.ChildElements()

		mapT = make(map[string]string, len(internalNodesT))
		for _, jv = range internalNodesT {
			mapT[jv.Tag] = jv.Text()
		}

		aryT = append(aryT, mapT)
	}

	return aryT, nil
}


xmlT = `<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
	<ZvendorNameFuzquery xmlns="urn:sap-com:document:sap:soap:functions:mc-style">
		<Iname xmlns="">北京大学</Iname>
		<Iresv1 xmlns="">简称:北大</Iresv1>
		<Iresv2 xmlns=""></Iresv2>
		<Tname xmlns="">
		</Tname>
	</ZvendorNameFuzquery>
</Body>
</Envelope>`

resultT = reshapeXMLX(xmlT)

println(resultT)

println("\n-----\n")

resultT = flattenXML(xmlT, "ZvendorNameFuzquery")

println(resultT)

println("\n-----\n")

resultT = getMSSFromXML(xmlT, "ZvendorNameFuzquery")

println(resultT)

println("\n-----\n")

xmlT = `<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
	<ZvendorNameFuzquery xmlns="urn:sap-com:document:sap:soap:functions:mc-style">
		<item>
			<Iname xmlns="">北京大学</Iname>
			<Iresv1 xmlns="">简称:北大</Iresv1>
			<Iresv2 xmlns=""></Iresv2>
			<Tname xmlns="">
			</Tname>
		</item>
		<item>
			<Iname xmlns="">清华大学</Iname>
			<Iresv1 xmlns=""></Iresv1>
			<Iresv2 xmlns="">地址</Iresv2>
			<Tname xmlns="">
			</Tname>
		</item>
	</ZvendorNameFuzquery>
</Body>
</Envelope>`

resultT = getMSSArrayFromXML(xmlT, "ZvendorNameFuzquery")

println(resultT)



首先,我们将使用github.com/beevik/etree包,这是一个Go语言中非常优秀的处理XML的第三方包。虽然可以直接按Gox约定的github_beevik_etree来使用该包,但为了代码简洁,在一开始我们给它定义了一个简称变量etree。

然后用etree.NewDocument()函数创建一个XML文档对象后,就可以进行各种处理了。

代码中的reshapeXMLX函数是将XML字符串进行重新格式化的函数;

flattenXML函数则是将XML中指定节点下的所有子节点提取出来生成一个数组(注意只能提取一级);

getMSSFromXML函数则是将XML中指定节点下的内容提取成为map[string]string格式的映射;

getMSSArrayFromXML函数则是用于提取一个数组,形式为[]map[string]string。

代码的执行结果如下:

λ gox scripts\xml.gox
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <ZvendorNameFuzquery xmlns="urn:sap-com:document:sap:soap:functions:mc-style">
      <Iname xmlns="">北京大学</Iname>
      <Iresv1 xmlns="">简称:北大</Iresv1>
      <Iresv2 xmlns=""/>
      <Tname xmlns=""/>
    </ZvendorNameFuzquery>
  </Body>
</Envelope>


-----

0xc000068c10: 北京大学
0xc000068c70: 简称:北大
0xc000068cd0:
0xc000068d30:


-----

[map[Iname:北京大学 Iresv1:简称:北大 Iresv2: Tname:
                ] <nil>]

-----

[[map[Iname:北京大学 Iresv1:简称:北大 Iresv2: Tname:
                        ] map[Iname:清华大学 Iresv1: Iresv2:地址 Tname:
                        ]] <nil>]

可以看到结果都符合预期。

至于如何生成XML文档、添加各种节点等,请参考etree的详细文档。


* 注:由于0.988版本后,为了减少不必要的文件体积,Gox已经放弃了其他脚本引擎,仅支持Qlang引擎,因此下面的内容已经无效,仅留作对旧版本的参考。

下面是Anko引擎版的代码:

tk = import("tk")
etree = import("etree")
strings = import("strings")

func reshapeXMLX(xmlA) {
	treeT = etree.NewDocument()

	if treeT == nil {
		return tk.GenerateErrorStringF("create XML tree failed")
	}

	errT = treeT.ReadFromString(xmlA)

	if errT != nil {
		return tk.GenerateErrorStringF("invalid XML: %v", errT)
	}

	treeT.Indent(2)

	outputT, errT = treeT.WriteToString()

	if errT != nil {
		return tk.GenerateErrorStringF("failed to reshape XML: %v", errT)
	}

	return outputT

}

func flattenXML(xmlA, nodeA) {
	treeT = etree.NewDocument()

	if treeT == nil {
		return tk.GenerateErrorStringF("create XML tree failed")
	}

	errT = treeT.ReadFromString(xmlA)

	if errT != nil {
		return tk.GenerateErrorStringF("invalid XML: %v", errT)
	}

	rootNodeT = treeT.FindElement("//" + nodeA)

	if rootNodeT == nil {
		return tk.GenerateErrorStringF("node not found: %v", nodeA)
	}

	nodesT = rootNodeT.ChildElements()

	bufT = make(strings.Builder)

	i = 0
	for v in nodesT {
		if i > 0 {
			bufT.WriteString("\n")
		}

		bufT.WriteString(tk.Spr("%v: %v", v.Tag, v.Text()))

		i++
	}

	return bufT.String()

}

func getMSSFromXML(xmlA, nodeA) {
	treeT = etree.NewDocument()

	if treeT == nil {
		return nil, tk.Errf("create XML tree failed")
	}

	errT = treeT.ReadFromString(xmlA)

	if errT != nil {
		return nil, tk.Errf("invalid XML: %v", errT)
	}

	rootNodeT = treeT.FindElement("//" + nodeA)

	if rootNodeT == nil {
		return nil, tk.Errf("node not found: %v", nodeA)
	}

	nodesT = rootNodeT.ChildElements()

	mapT = make(map[string]string, len(nodesT))
	for jv in nodesT {
		mapT[jv.Tag] = jv.Text()
	}

	return mapT, nil
}

func getMSSArrayFromXML(xmlA, nodeA) {
	treeT = etree.NewDocument()

	if treeT == nil {
		return nil, tk.Errf("create XML tree failed")
	}

	errT = treeT.ReadFromString(xmlA)

	if errT != nil {
		return nil, tk.Errf("invalid XML: %v", errT)
	}

	rootNodeT = treeT.FindElement("//" + nodeA)

	if rootNodeT == nil {
		return nil, tk.Errf("node not found: %v", nodeA)
	}

	nodesT = rootNodeT.ChildElements()

	aryT = make([]map[string]string, 0)

	for v in nodesT {
		internalNodesT = v.ChildElements()

		mapT = make(map[string]string, len(internalNodesT))
		for jv in internalNodesT {
			mapT[jv.Tag] = jv.Text()
		}

		aryT += mapT
	}

	return aryT, nil
}


xmlT = `<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
	<ZvendorNameFuzquery xmlns="urn:sap-com:document:sap:soap:functions:mc-style">
		<Iname xmlns="">北京大学</Iname>
		<Iresv1 xmlns="">简称:北大</Iresv1>
		<Iresv2 xmlns=""></Iresv2>
		<Tname xmlns="">
		</Tname>
	</ZvendorNameFuzquery>
</Body>
</Envelope>`

resultT = reshapeXMLX(xmlT)

println(resultT)

println("\n-----\n")

resultT = flattenXML(xmlT, "ZvendorNameFuzquery")

println(resultT)

println("\n-----\n")

resultT = getMSSFromXML(xmlT, "ZvendorNameFuzquery")

println(resultT)

println("\n-----\n")

xmlT = `<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
	<ZvendorNameFuzquery xmlns="urn:sap-com:document:sap:soap:functions:mc-style">
		<item>
			<Iname xmlns="">北京大学</Iname>
			<Iresv1 xmlns="">简称:北大</Iresv1>
			<Iresv2 xmlns=""></Iresv2>
			<Tname xmlns="">
			</Tname>
		</item>
		<item>
			<Iname xmlns="">清华大学</Iname>
			<Iresv1 xmlns=""></Iresv1>
			<Iresv2 xmlns="">地址</Iresv2>
			<Tname xmlns="">
			</Tname>
		</item>
	</ZvendorNameFuzquery>
</Body>
</Envelope>`

resultT = getMSSArrayFromXML(xmlT, "ZvendorNameFuzquery")

println(resultT)


代码的执行结果如下:

λ gox scripts\xml.gox
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Body>
    <ZvendorNameFuzquery xmlns="urn:sap-com:document:sap:soap:functions:mc-style">
      <Iname xmlns="">北京大学</Iname>
      <Iresv1 xmlns="">简称:北大</Iresv1>
      <Iresv2 xmlns=""/>
      <Tname xmlns=""/>
    </ZvendorNameFuzquery>
  </Body>
</Envelope>


-----

Iname: 北京大学
Iresv1: 简称:北大
Iresv2:
Tname:


-----

[map[Iname:北京大学 Iresv1:简称:北大 Iresv2: Tname:
                ] <nil>]

-----

[[map[Iname:北京大学 Iresv1:简称:北大 Iresv2: Tname:
                        ] map[Iname:清华大学 Iresv1: Iresv2:地址 Tname:
                        ]] <nil>]

猜你喜欢

转载自blog.csdn.net/weixin_41462458/article/details/108055065