type OpenXmlElement = class public function Create(_node: XmlNode);overload; function Create(_parent: tslobj; _prefix: string; _local_name: string);overload; function Init();virtual; function InitNode(_node: XmlNode);virtual; function Copy(_obj: tslobj);virtual; function Clone(): OpenXmlElement;virtual; function Deserialize();virtual; function Serialize();virtual; function Marshal(): tableArray;virtual; function SetFallback(_fallback: OpenXmlElement); function RemoveAttribute(_attr: OpenXmlAttribute); function Attribute(_attr: string; _ns: string): OpenXmlAttribute; function Attributes(): array of OpenXmlAttribute; function Elements(): array of tslobj; function Xmlns(_prefix: string): string; // 单位转换 function ConvertToPoint();virtual; protected function GetNode(): XmlNode; function DeleteSelf(): boolean; public LocalName: string; // 本地名称 [weakref]Parent: tslobj; // 父类 Prefix: string; // 前缀 XmlNode: XmlNode; // XMLNode节点 ElementName: string; Removed: boolean; // 节点删除标记,最后Serialize时候统一删除 Enable: boolean; // 是否启用 没有属性 protected attributes_: array of OpenXmlAttribute; // 属性 attributes_pf_: tableArray; xmlns_: tableArray; sorted_child_: tableArray; container_: TSOfficeContainer; fallback_: OpenXmlElement; // 代理对象 deserialized_: boolean; // 是否已反序列化 end; function OpenXmlElement.Create(_node: XmlNode);overload; begin node_name := _node.GetName(); pos := Pos(":", node_name); if pos then {self.}Create(nil, node_name[:pos-1], node_name[pos+1:]); else {self.}Create(nil, nil, node_name); {self.}InitNode(_node); end; function OpenXmlElement.Create(_parent: tslobj; _prefix: string; _local_name: string);overload; begin {self.}Parent := _parent; {self.}Prefix := _prefix; {self.}LocalName := _local_name; {self.}XmlNode := nil; {self.}ElementName := ifString({self.}Prefix) and {self.}Prefix <> "" ? format("%s:%s", {self.}Prefix, {self.}LocalName) : {self.}LocalName; {self.}Removed := false; {self.}Enable := false; {self.}Init(); xmlns_ := array(); fallback_ := nil; deserialized_ := false; end; function OpenXmlElement.SetFallback(_fallback: OpenXmlElement); begin fallback_ := _fallback; end; function OpenXmlElement.Attribute(_attr: string; _ns: string): OpenXmlAttribute; begin if ifnil(_ns) then attr_name := ifString({self.}Prefix) and {self.}Prefix <> "" ? format("%s:%s", {self.}Prefix, _attr) : _attr; else attr_name := format("%s:%s", _ns, _attr); return attributes_[attr_name]; end; function OpenXmlElement.Attributes(): array of OpenXmlAttribute; begin attrs := array(); for k,v in attributes_ do if not ifnil(v.Value) then attrs[length(attrs)] := v; return attrs; end; function OpenXmlElement.Elements(): array of tslobj; begin return container_.GetElements(false); end; function OpenXmlElement.Xmlns(_prefix: string): string; begin k := ifnil(_prefix) ? "xmlns" : "xmlns:" + _prefix; if tslassigning then begin if ifnil(xmlns_[k]) then xmlns_[k] := ifnil(_prefix) ? new OpenXmlAttribute("", "xmlns", nil) : new OpenXmlAttribute("xmlns", _prefix, nil); end return xmlns_[k]; end; function OpenXmlElement.GetNode(): XmlNode; begin if not ifObj({self.}XmlNode) then {self.}XmlNode := {self.}Parent.GetOrCreateNode(self); return {self.}XmlNode; end; function OpenXmlElement.DeleteSelf(): boolean; begin if {self.}Removed then begin if {self.}XmlNode then {self.}Parent.XmlNode.DeleteChild({self.}XmlNode); return true; end return false; end; function OpenXmlElement.RemoveAttribute(_attr: OpenXmlAttribute); begin _attr.Value := nil; end;