XML数据结构
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Zeebe Modeler" exporterVersion="0.1.0">
<bpmn:process id="order-process" isExecutable="true">
<bpmn:startEvent id="order-placed" name="Order Placed">
<bpmn:outgoing>SequenceFlow_18tqka5</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:endEvent id="order-delivered" name="Order Delivered">
<bpmn:incoming>SequenceFlow_1qj94z0</bpmn:incoming>
</bpmn:endEvent>
</bpmn:process>
</bpmn:definitions>
解析(反序列化)
- 定义结构体
type bp struct {
XMLName xml.Name `xml:"http://www.omg.org/spec/BPMN/20100524/MODEL definitions"`
// <!--attributes start-->
BPMN string `xml:"bpmn,attr"`
BPMNDI string `xml:"bpmndi,attr"`
DI string `xml:"di,attr"`
DC string `xml:"dc,attr"`
Zeebe string `xml:"zeebe,attr"`
XSI string `xml:"xsi,attr"`
ID string `xml:"id,attr"`
TargetNamespace string `xml:"targetNamespace,attr"`
Exporter string `xml:"exporter,attr"`
ExporterVersion string `xml:"exporterVersion,attr"`
// <!--attributes end-->
Process struct {
// <!--attributes start-->
ID string `xml:"id,attr"`
Name string `xml:"name,attr"`
IsExecutable bool `xml:"isExecutable,attr"`
// <!--attributes end-->
StartEvent struct {
// <!--attributes start-->
ID string `xml:"id,attr"`
Name string `xml:"name,attr"`
// <!--attributes end-->
Outgoing string `xml:"http://www.omg.org/spec/BPMN/20100524/MODEL outgoing"`
} `xml:"http://www.omg.org/spec/BPMN/20100524/MODEL startEvent"`
EndEvent struct {
// <!--attributes start-->
ID string `xml:"id,attr"`
Name string `xml:"name,attr"`
// <!--attributes end-->
Incoming string `xml:"http://www.omg.org/spec/BPMN/20100524/MODEL incoming"`
} `xml:"http://www.omg.org/spec/BPMN/20100524/MODEL endEvent"`
} `xml:"http://www.omg.org/spec/BPMN/20100524/MODEL process"`
}
- 解析
var target bp
err = xml.Unmarshal(bpmn, &target)
if err != nil {
fmt.Println("parse xml file error: ", err)
}
fmt.Println("Print xml struct:")
fmt.Println(target, target.BPMNDI, target.ExporterVersion)
fmt.Println(target.Process.IsExecutable)
fmt.Println(target.Process.StartEvent.Outgoing)
序列化
值得注意的是,直接使用上面的bp
结构体序列化为xml字符串会发现结果的结构与预期并不一致。golang playground
相关issue #9519
解决方案
解决方案是将序列化(Marshal)和反序列化(Unmarshal)的结构体分别定义。golang playground
- 定义结构体(仅修改了部分)
type bpEn struct {
XMLName xml.Name `xml:"bpmn:definitions"` // <----- 修改
// <!--attributes start-->
BPMN string `xml:"xmlns:bpmn,attr"` // <---- 修改
BPMNDI string `xml:"bpmndi,attr"`
DI string `xml:"di,attr"`
DC string `xml:"dc,attr"`
Zeebe string `xml:"zeebe,attr"`
XSI string `xml:"xsi,attr"`
ID string `xml:"id,attr"`
TargetNamespace string `xml:"targetNamespace,attr"`
Exporter string `xml:"exporter,attr"`
ExporterVersion string `xml:"exporterVersion,attr"`
// <!--attributes end-->
Process struct {
// <!--attributes start-->
ID string `xml:"id,attr"`
Name string `xml:"name,attr"`
IsExecutable bool `xml:"isExecutable,attr"`
// <!--attributes end-->
StartEvent struct {
// <!--attributes start-->
ID string `xml:"id,attr"`
Name string `xml:"name,attr"`
// <!--attributes end-->
Outgoing string `xml:"http://www.omg.org/spec/BPMN/20100524/MODEL outgoing"`
} `xml:"http://www.omg.org/spec/BPMN/20100524/MODEL startEvent"`
EndEvent struct {
// <!--attributes start-->
ID string `xml:"id,attr"`
Name string `xml:"name,attr"`
// <!--attributes end-->
Incoming string `xml:"http://www.omg.org/spec/BPMN/20100524/MODEL incoming"`
} `xml:"http://www.omg.org/spec/BPMN/20100524/MODEL endEvent"`
} `xml:"http://www.omg.org/spec/BPMN/20100524/MODEL process"`
}
- 序列化
bpmn := []byte(`<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Zeebe Modeler" exporterVersion="0.1.0">
<bpmn:process id="order-process" isExecutable="true">
<bpmn:startEvent id="order-placed" name="Order Placed">
<bpmn:outgoing>SequenceFlow_18tqka5</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:endEvent id="order-delivered" name="Order Delivered">
<bpmn:incoming>SequenceFlow_1qj94z0</bpmn:incoming>
</bpmn:endEvent>
</bpmn:process>
</bpmn:definitions>`)
var en bpEn
en.Process.IsExecutable = false
en.Process.ID = "identity"
en.Process.Name = "Hello Someone"
en.Process.StartEvent.Outgoing = "xyz"
enSt, err := xml.MarshalIndent(&en, "", " ")
fmt.Println("原本结构:\n", string(bpmn), "\n", "序列化后结构:\n", string(enSt), err)
return
参考文章:
https://blog.csdn.net/qq_24210767/article/details/102829205
https://studygolang.com/articles/5328