type OpenXmlCompositeElement = class(OpenXmlElement) public function InitNode(_node: XmlNode);override; function Deserialize();override; function Serialize();override; function Marshal(): tableArray;override; public function AppendChild(_element: OpenXmlElement); function InsertAfter(_element: OpenXmlElement; _pos_element: OpenXmlElement); function RemoveChild(_element: OpenXmlElement); function RemoveAttribute(_attr: OpenXmlAttribute); // function InsertBefore(_pos_obj: tslobj; _obj: tslobj); // function PrependChild(_obj: tslobj); // function SetAttribute(_obj: OpenXmlAttribute); // function RemoveAttribute(); public function GetOrCreateNode(_obj: tslobj); end; function OpenXmlCompositeElement.InitNode(_node: XmlNode);override; begin {self.}XmlNode := _node; if not _node then return; tslassigning_backup := tslassigning; tslassigning := 1; node := _node.FirstChild(); while ifObj(node) do begin node_name := node.GetName(); arr := sorted_child_[node_name]; if ifarray(arr) then begin pf := arr[1]; obj := pf.Do(); obj.InitNode(node); end node := node.NextElement(); end tslassigning := tslassigning_backup; end; function OpenXmlCompositeElement.Deserialize();override; begin if not ifObj({self.}XmlNode) then return; attrs := {self.}XmlNode.Attributes(); for k, v in attrs do begin pos := pos("xmlns", k); if pos then begin xmlns_[k] := k = "xmlns" ? new OpenXmlAttribute("", "xmlns", v) : new OpenXmlattribute("xmlns", k[pos+6:], v); continue; end pf := attributes_pf_[k]; if ifnil(pf) then continue; pf.Do(v); end child_elements := container_.GetElements(); for k, v in child_elements do v.Deserialize(); end; function OpenXmlCompositeElement.Serialize();override; begin if {self.}DeleteSelf() then return; // xmlns for k, v in xmlns_ do {self.}GetNode().SetAttribute(v.ElementName, v.Value); // Attributes for k, v in attributes_ do if not ifnil(v.Value) then {self.}GetNode().SetAttribute(v.ElementName, v.Value); else if {self.}XmlNode then {self.}XmlNode.DeleteAttribute(v.ElementName); // Children child_elements := container_.GetElements(); for k, v in child_elements do v.Serialize(); end; function OpenXmlCompositeElement.Marshal(): tableArray;override; begin child_elements := container_.GetElements(false); child_arr := array(); for k, v in child_elements do begin arr := array("type": "element", "name": v.ElementName, "attributes": array()); if v is Class(OpenXmlTextElement) or v is Class(OpenXmlCompositeElement) then begin marshal := v.Marshal(); if length(marshal["children"]) = 0 and length(marshal["attributes"]) = 0 then continue; arr["children"] := marshal["children"]; arr["attributes"] union= marshal["attributes"]; child_arr[length(child_arr)] := arr; end else if v is Class(OpenXmlSimpleType) then begin marshal := v.Marshal(); if length(marshal) > 0 then child_arr[length(child_arr)] := arr; end else begin echo "error = marshal.\n"; end end tmp_arr := array("type": "element", "name": {self.}ElementName, "children": child_arr, "attributes": array()); for k,v in attributes_ do begin if not ifnil(v.Value) then tmp_arr["attributes"][v.ElementName] := v.Value; end return tmp_arr; end; function OpenXmlCompositeElement.GetOrCreateNode(_obj: tslobj); begin if not ifObj({self.}XmlNode) then {self.}XmlNode := {self.}Parent.GetOrCreateNode(self); nearest_node := nil; child_elements := container_.GetElements(false); for k, v in child_elements do begin if ifObj(v.XmlNode) then nearest_node := v.XmlNode; if v = _obj then begin if ifObj(v.XmlNode) then return v.XmlNode; if ifnil(nearest_node) then return {self.}XmlNode.InsertFirstChild("element", _obj.ElementName); else return {self.}XmlNode.InsertAfterChild(nearest_node, "element", _obj.ElementName); end end raise "No child."; end; function OpenXmlCompositeElement.AppendChild(_element: OpenXmlElement); begin container_.Append(_element); end; function OpenXmlCompositeElement.InsertAfter(_element: OpenXmlElement; _pos_element: OpenXmlElement); begin container_.InsertAfter(_element, _pos_element); end; function OpenXmlCompositeElement.RemoveChild(_element: OpenXmlElement); begin _element.Removed := true; end; function OpenXmlCompositeElement.RemoveAttribute(_attr: OpenXmlAttribute); begin _attr.Value := nil; end;