feat: 支持clone方法

feat: 支持反序列化的缓存,第二次反序列化不会执行操作
feat: openxmlelement类支持Enable属性来控制节点是否生成
This commit is contained in:
csh 2025-08-06 18:14:09 +08:00
parent b7a7b983b3
commit 7a65e50157
9 changed files with 20255 additions and 5933 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,28 +3,30 @@ interface
type SldLayoutId = class(OpenXmlCompositeElement) type SldLayoutId = class(OpenXmlCompositeElement)
public public
function Create();overload; function Create();overload;
function Create(_node: XmlNode);overload; function Create(_node: XmlNode);overload;
function Create(_parent: tslobj; _prefix: string; _local_name: string);overload; function Create(_parent: tslobj; _prefix: string; _local_name: string);overload;
function Init();override; function Init();override;
function Copy(_obj: SldLayoutId);override; function Copy(_obj: SldLayoutId);override;
public function ConvertToPoint();override;
// attributes property
property Id read ReadXmlAttrId write WriteXmlAttrId;
property Id read ReadXmlAttrId write WriteXmlAttrId;
property Id read ReadXmlAttrId write WriteXmlAttrId;
function ReadXmlAttrId();
function WriteXmlAttrId(_value);
function ReadXmlAttrId();
function WriteXmlAttrId(_value);
function ReadXmlAttrId();
function WriteXmlAttrId(_value);
public public
// Attributes // attributes property
XmlAttrId: OpenXmlAttribute; property Id read ReadXmlAttrId write WriteXmlAttrId;
XmlAttrId: OpenXmlAttribute; property IdN read ReadXmlAttrIdN write WriteXmlAttrIdN;
XmlAttrId: OpenXmlAttribute; property RId read ReadXmlAttrRId write WriteXmlAttrRId;
function ReadXmlAttrId(_ns: string);
function WriteXmlAttrId(_p1: any; _p2: any);
function ReadXmlAttrIdN();
function WriteXmlAttrIdN(_value: any);
function ReadXmlAttrRId();
function WriteXmlAttrRId(_value: any);
public
// Attributes
XmlAttrId: OpenXmlAttribute;
XmlAttrIdN: OpenXmlAttribute;
XmlAttrRId: OpenXmlAttribute;
end; end;
@ -32,91 +34,107 @@ implementation
function SldLayoutId.Create();overload; function SldLayoutId.Create();overload;
begin begin
{self.}Create(nil, "p", "sldLayoutId"); {self.}Create(nil, "p", "sldLayoutId");
end; end;
function SldLayoutId.Create(_node: XmlNode);overload; function SldLayoutId.Create(_node: XmlNode);overload;
begin begin
class(OpenXmlCompositeElement).Create(_node: XmlNode); inherited Create(_node);
end; end;
function SldLayoutId.Create(_parent: tslobj; _prefix: string; _local_name: string);overload; function SldLayoutId.Create(_parent: tslobj; _prefix: string; _local_name: string);overload;
begin begin
setsysparam(pn_calcctrlword(), getsysparam(pn_calcctrlword()) .| 0x200); setsysparam(pn_calcctrlword(), getsysparam(pn_calcctrlword()) .| 0x200);
class(OpenXmlCompositeElement).Create(_parent, _prefix, _local_name); inherited Create(_parent, _prefix, _local_name);
end; end;
function SldLayoutId.Init();override; function SldLayoutId.Init();override;
begin begin
pre := {self.}Prefix ? {self.}Prefix + ":" : ""; pre := {self.}Prefix ? {self.}Prefix + ":" : "";
attributes_ := array(); attributes_ := array();
attributes_pf_ := array( attributes_pf_ := array(
pre + "id": makeweakref(thisFunction(WriteXmlAttrId)), pre + "id": makeweakref(thisFunction(WriteXmlAttrId)),
"id": makeweakref(thisFunction(WriteXmlAttrId)), "id": makeweakref(thisFunction(WriteXmlAttrIdN)),
"r:id": makeweakref(thisFunction(WriteXmlAttrId)), "r:id": makeweakref(thisFunction(WriteXmlAttrRId)),
); );
sorted_child_ := array( sorted_child_ := array(
); );
container_ := new TSOfficeContainer(sorted_child_); container_ := new TSOfficeContainer(sorted_child_);
end; end;
function SldLayoutId.Copy(_obj: SldLayoutId);override; function SldLayoutId.Copy(_obj: SldLayoutId);override;
begin begin
tslassigning_backup := tslassigning; tslassigning_backup := tslassigning;
tslassigning := 1; tslassigning := 1;
class(OpenXmlCompositeElement).Copy(_obj); class(OpenXmlCompositeElement).Copy(_obj);
if not ifnil(_obj.Id) then if not ifnil(_obj.Id) then
{self.}Id := _obj.Id; {self.}Id := _obj.Id;
if not ifnil(_obj.Id) then if not ifnil(_obj.IdN) then
{self.}Id := _obj.Id; {self.}IdN := _obj.IdN;
if not ifnil(_obj.Id) then if not ifnil(_obj.RId) then
{self.}Id := _obj.Id; {self.}RId := _obj.RId;
tslassigning := tslassigning_backup; tslassigning := tslassigning_backup;
end; end;
function SldLayoutId.ReadXmlAttrId(); function SldLayoutId.ConvertToPoint();override;
begin begin
return {self.}XmlAttrId.Value;
end; end;
function SldLayoutId.WriteXmlAttrId(_value); function SldLayoutId.ReadXmlAttrId(_ns: string);
begin begin
if ifnil({self.}XmlAttrId) then if _ns = "" then
begin return {self.}ReadXmlAttrIdN();
{self.}XmlAttrId := new OpenXmlAttribute({self.}Prefix, "id", nil); if _ns = "r" then
attributes_[length(attributes_)] := {self.}XmlAttrId; return {self.}ReadXmlAttrRId();
end return ifnil({self.}XmlAttrId.Value) ? fallback_.XmlAttrId.Value : {self.}XmlAttrId.Value;
{self.}XmlAttrId.Value := _value;
end; end;
function SldLayoutId.ReadXmlAttrId(); function SldLayoutId.WriteXmlAttrId(_p1: any; _p2: any);
begin begin
return {self.}XmlAttrId.Value; if realparamcount = 2 then
begin
if _p1 = "" then
return {self.}WriteXmlAttrIdN(_p2);
if _p1 = "r" then
return {self.}WriteXmlAttrRId(_p2);
end
if ifnil({self.}XmlAttrId) then
begin
{self.}XmlAttrId := new OpenXmlAttribute({self.}Prefix, "id", nil);
attributes_[{self.}Prefix ? {self.}Prefix + ":" + "id" : "id"] := {self.}XmlAttrId;
end
{self.}XmlAttrId.Value := realparamcount = 1 ? _p1 : _p2;
end; end;
function SldLayoutId.WriteXmlAttrId(_value); function SldLayoutId.ReadXmlAttrIdN();
begin begin
if ifnil({self.}XmlAttrId) then return ifnil({self.}XmlAttrIdN.Value) ? fallback_.XmlAttrIdN.Value : {self.}XmlAttrIdN.Value;
begin
{self.}XmlAttrId := new OpenXmlAttribute("", "id", nil);
attributes_[length(attributes_)] := {self.}XmlAttrId;
end
{self.}XmlAttrId.Value := _value;
end; end;
function SldLayoutId.ReadXmlAttrId(); function SldLayoutId.WriteXmlAttrIdN(_value: any);
begin begin
return {self.}XmlAttrId.Value; if ifnil({self.}XmlAttrIdN) then
begin
{self.}XmlAttrIdN := new OpenXmlAttribute("", "id", nil);
attributes_["id"] := {self.}XmlAttrIdN;
end
{self.}XmlAttrIdN.Value := _value;
end; end;
function SldLayoutId.WriteXmlAttrId(_value); function SldLayoutId.ReadXmlAttrRId();
begin begin
if ifnil({self.}XmlAttrId) then return ifnil({self.}XmlAttrRId.Value) ? fallback_.XmlAttrRId.Value : {self.}XmlAttrRId.Value;
begin end;
{self.}XmlAttrId := new OpenXmlAttribute("r", "id", nil);
attributes_[length(attributes_)] := {self.}XmlAttrId; function SldLayoutId.WriteXmlAttrRId(_value: any);
end begin
{self.}XmlAttrId.Value := _value; if ifnil({self.}XmlAttrRId) then
begin
{self.}XmlAttrRId := new OpenXmlAttribute("r", "id", nil);
attributes_["r:id"] := {self.}XmlAttrRId;
end
{self.}XmlAttrRId.Value := _value;
end; end;
end. end.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ public
function AppendChild(_element: OpenXmlElement); function AppendChild(_element: OpenXmlElement);
function InsertAfter(_element: OpenXmlElement; _pos_element: OpenXmlElement); function InsertAfter(_element: OpenXmlElement; _pos_element: OpenXmlElement);
function RemoveChild(_element: OpenXmlElement); function RemoveChild(_element: OpenXmlElement);
// function InsertBefore(_pos_obj: tslobj; _obj: tslobj); function InsertBefore(_element: OpenXmlElement; _pos_element: OpenXmlElement);
// function PrependChild(_obj: tslobj); // function PrependChild(_obj: tslobj);
// function SetAttribute(_obj: OpenXmlAttribute); // function SetAttribute(_obj: OpenXmlAttribute);
@ -37,11 +37,12 @@ begin
node := node.NextElement(); node := node.NextElement();
end end
tslassigning := tslassigning_backup; tslassigning := tslassigning_backup;
deserialized_ := false;
end; end;
function OpenXmlCompositeElement.Deserialize();override; function OpenXmlCompositeElement.Deserialize();override;
begin begin
if not ifObj({self.}XmlNode) then return; if deserialized_ or not ifObj({self.}XmlNode) then return;
attrs := {self.}XmlNode.Attributes(); attrs := {self.}XmlNode.Attributes();
for k, v in attrs do for k, v in attrs do
begin begin
@ -58,23 +59,27 @@ begin
child_elements := container_.GetElements(); child_elements := container_.GetElements();
for k, v in child_elements do for k, v in child_elements do
v.Deserialize(); v.Deserialize();
deserialized_ := true;
end; end;
function OpenXmlCompositeElement.Serialize();override; function OpenXmlCompositeElement.Serialize();override;
begin begin
if {self.}DeleteSelf() then return; if {self.}DeleteSelf() then return;
{self.}GetNode(); if {self.}Enable then {self.}GetNode();
// xmlns // xmlns
for k, v in xmlns_ do for k, v in xmlns_ do
{self.}XmlNode.SetAttribute(v.ElementName, v.Value); if not ifnil(v.Value) then
{self.}GetNode().SetAttribute(v.ElementName, v.Value);
else if {self.}XmlNode then
{self.}GetNode().DeleteAttribute(v.ElementName);
// Attributes // Attributes
for k, v in attributes_ do for k, v in attributes_ do
if not ifnil(v.Value) then if not ifnil(v.Value) then
{self.}XmlNode.SetAttribute(v.ElementName, v.Value); {self.}GetNode().SetAttribute(v.ElementName, v.Value);
else if {self.}XmlNode then else if {self.}XmlNode then
{self.}XmlNode.DeleteAttribute(v.ElementName); {self.}GetNode().DeleteAttribute(v.ElementName);
// Children // Children
child_elements := container_.GetElements(); child_elements := container_.GetElements();
@ -89,7 +94,7 @@ begin
for k, v in child_elements do for k, v in child_elements do
begin begin
arr := array("type": "element", "name": v.ElementName, "attributes": array()); arr := array("type": "element", "name": v.ElementName, "attributes": array());
if v is Class(OpenXmlTextElement) or v is Class(OpenXmlCompositeElement) then if v is class(OpenXmlTextElement) or v is class(OpenXmlCompositeElement) then
begin begin
marshal := v.Marshal(); marshal := v.Marshal();
if length(marshal["children"]) = 0 and length(marshal["attributes"]) = 0 then continue; if length(marshal["children"]) = 0 and length(marshal["attributes"]) = 0 then continue;
@ -97,7 +102,7 @@ begin
arr["attributes"] union= marshal["attributes"]; arr["attributes"] union= marshal["attributes"];
child_arr[length(child_arr)] := arr; child_arr[length(child_arr)] := arr;
end end
else if v is Class(OpenXmlSimpleType) then else if v is class(OpenXmlSimpleType) then
begin begin
marshal := v.Marshal(); marshal := v.Marshal();
if length(marshal) > 0 then child_arr[length(child_arr)] := arr; if length(marshal) > 0 then child_arr[length(child_arr)] := arr;
@ -138,11 +143,13 @@ end;
function OpenXmlCompositeElement.AppendChild(_element: OpenXmlElement); function OpenXmlCompositeElement.AppendChild(_element: OpenXmlElement);
begin begin
_element.Parent := self;
container_.Append(_element); container_.Append(_element);
end; end;
function OpenXmlCompositeElement.InsertAfter(_element: OpenXmlElement; _pos_element: OpenXmlElement); function OpenXmlCompositeElement.InsertAfter(_element: OpenXmlElement; _pos_element: OpenXmlElement);
begin begin
_element.Parent := self;
container_.InsertAfter(_element, _pos_element); container_.InsertAfter(_element, _pos_element);
end; end;
@ -151,3 +158,8 @@ begin
_element.Removed := true; _element.Removed := true;
end; end;
function OpenXmlCompositeElement.InsertBefore(_element: OpenXmlElement; _pos_element: OpenXmlElement);
begin
_element.Parent := self;
container_.InsertBefore(_element, _pos_element);
end;

View File

@ -5,6 +5,7 @@ public
function Init();virtual; function Init();virtual;
function InitNode(_node: XmlNode);virtual; function InitNode(_node: XmlNode);virtual;
function Copy(_obj: tslobj);virtual; function Copy(_obj: tslobj);virtual;
function Clone(): OpenXmlElement;virtual;
function Deserialize();virtual; function Deserialize();virtual;
function Serialize();virtual; function Serialize();virtual;
function Marshal(): tableArray;virtual; function Marshal(): tableArray;virtual;
@ -31,6 +32,8 @@ public
ElementName: string; ElementName: string;
Removed: boolean; // 节点删除标记最后Serialize时候统一删除 Removed: boolean; // 节点删除标记最后Serialize时候统一删除
Enable: boolean; // 是否启用 <b /> 没有属性
protected protected
attributes_: array of OpenXmlAttribute; // 属性 attributes_: array of OpenXmlAttribute; // 属性
attributes_pf_: tableArray; attributes_pf_: tableArray;
@ -38,6 +41,7 @@ protected
sorted_child_: tableArray; sorted_child_: tableArray;
container_: TSOfficeContainer; container_: TSOfficeContainer;
fallback_: OpenXmlElement; // 代理对象 fallback_: OpenXmlElement; // 代理对象
deserialized_: boolean; // 是否已反序列化
end; end;
function OpenXmlElement.Create(_node: XmlNode);overload; function OpenXmlElement.Create(_node: XmlNode);overload;
@ -57,9 +61,11 @@ begin
{self.}XmlNode := nil; {self.}XmlNode := nil;
{self.}ElementName := ifString({self.}Prefix) and {self.}Prefix <> "" ? format("%s:%s", {self.}Prefix, {self.}LocalName) : {self.}LocalName; {self.}ElementName := ifString({self.}Prefix) and {self.}Prefix <> "" ? format("%s:%s", {self.}Prefix, {self.}LocalName) : {self.}LocalName;
{self.}Removed := false; {self.}Removed := false;
{self.}Enable := false;
{self.}Init(); {self.}Init();
xmlns_ := array(); xmlns_ := array();
fallback_ := nil; fallback_ := nil;
deserialized_ := false;
end; end;
function OpenXmlElement.SetFallback(_fallback: OpenXmlElement); function OpenXmlElement.SetFallback(_fallback: OpenXmlElement);

View File

@ -3,6 +3,7 @@ public
function Init();override; function Init();override;
function InitNode(_node: XmlNode);override; function InitNode(_node: XmlNode);override;
function Copy(_obj: tslobj);override; function Copy(_obj: tslobj);override;
function Clone(): OpenXmlSimpleType;override;
function Deserialize();override; function Deserialize();override;
function Serialize();override; function Serialize();override;
function Marshal(): tableArray;override; function Marshal(): tableArray;override;
@ -18,27 +19,33 @@ public
// IsApplied: boolean; // 是否已经应用和val值有关 // IsApplied: boolean; // 是否已经应用和val值有关
property IsApplied read ReadIsApplied; property IsApplied read ReadIsApplied;
function ReadIsApplied(); function ReadIsApplied();
public
Enable: boolean; // 是否启用 <b /> 没有属性需要通过val写属性
end; end;
function OpenXmlSimpleType.Init();override; function OpenXmlSimpleType.Init();override;
begin begin
{self.}Enable := false; // {self.}Enable := false;
end; end;
function OpenXmlSimpleType.InitNode(_node: XmlNode);override; function OpenXmlSimpleType.InitNode(_node: XmlNode);override;
begin begin
{self.}XmlNode := ifObj(_node) ? _node : nil; {self.}XmlNode := ifObj(_node) ? _node : nil;
deserialized_ := false;
end; end;
function OpenXmlSimpleType.Copy(_obj: tslobj);override; function OpenXmlSimpleType.Copy(_obj: tslobj);override;
begin begin
if not ifnil(_obj.Enable) then {self.}Enable := _obj.Enable; {self.}Enable := _obj.Enable;
if not ifnil(_obj.XmlAttrVal.Value) then {self.}Val := _obj.XmlAttrVal.Value; if not ifnil(_obj.XmlAttrVal.Value) then {self.}Val := _obj.XmlAttrVal.Value;
end; end;
function OpenXmlSimpleType.Clone(): OpenXmlSimpleType;override;
begin
obj := new OpenXmlSimpleType(nil, {self.}Prefix, {self.}LocalName);
obj.Enable := {self.}Enable;
if not ifnil({self.}XmlAttrVal.Value) then obj.Val := {self.}XmlAttrVal.Value;
return obj;
end;
function OpenXmlSimpleType.Marshal(): tableArray;override; function OpenXmlSimpleType.Marshal(): tableArray;override;
begin begin
if not {self.}Enable then return array(); if not {self.}Enable then return array();
@ -50,6 +57,7 @@ end;
function OpenXmlSimpleType.Deserialize();override; function OpenXmlSimpleType.Deserialize();override;
begin begin
if deserialized_ then return;
if ifObj({self.}XmlNode) then if ifObj({self.}XmlNode) then
begin begin
attrs := {self.}XmlNode.Attributes(); attrs := {self.}XmlNode.Attributes();
@ -67,13 +75,14 @@ begin
{self.}Enable := false; {self.}Enable := false;
{self.}XmlAttrVal := nil; {self.}XmlAttrVal := nil;
end end
deserialized_ := true;
end; end;
function OpenXmlSimpleType.Serialize();override; function OpenXmlSimpleType.Serialize();override;
begin begin
if not ifObj({self.}XmlNode) then if not ifObj({self.}XmlNode) then
begin begin
{self.}GetNode(); if {self.}Enable then {self.}GetNode();
if not ifnil({self.}XmlAttrVal.Value) then {self.}XmlNode.SetAttribute({self.}XmlAttrVal.ElementName, {self.}XmlAttrVal.Value); if not ifnil({self.}XmlAttrVal.Value) then {self.}XmlNode.SetAttribute({self.}XmlAttrVal.ElementName, {self.}XmlAttrVal.Value);
end end
else begin else begin
@ -102,6 +111,6 @@ end;
function OpenXmlSimpleType.ReadIsApplied(); function OpenXmlSimpleType.ReadIsApplied();
begin begin
if {self.}Enable then if {self.}Enable then
return {self.}XmlAttrVal.Value = "0" or {self.}XmlAttrVal.Value = "false" ? false : true; return {self.}XmlAttrVal.Value = "0" or {self.}XmlAttrVal.Value = "false" or {self.}XmlAttrVal.Value = "off" ? false : true;
return false; return false;
end; end;

View File

@ -2,6 +2,7 @@ type OpenXmlTextElement = class(OpenXmlElement)
public public
function InitNode(_node: XmlNode);override; function InitNode(_node: XmlNode);override;
function Copy(_obj: tslobj);virtual; function Copy(_obj: tslobj);virtual;
function Clone(): OpenXmlTextElement;virtual;
function Deserialize();override; function Deserialize();override;
function Serialize();override; function Serialize();override;
function Marshal(): tableArray;override; function Marshal(): tableArray;override;
@ -13,6 +14,7 @@ end;
function OpenXmlTextElement.InitNode(_node: XmlNode);override; function OpenXmlTextElement.InitNode(_node: XmlNode);override;
begin begin
{self.}XmlNode := ifObj(_node) ? _node : nil; {self.}XmlNode := ifObj(_node) ? _node : nil;
deserialized_ := false;
end; end;
function OpenXmlTextElement.Copy(_obj: tslobj);virtual; function OpenXmlTextElement.Copy(_obj: tslobj);virtual;
@ -20,6 +22,13 @@ begin
if not ifnil(_obj.Text) then {self.}Text := _obj.Text; if not ifnil(_obj.Text) then {self.}Text := _obj.Text;
end; end;
function OpenXmlTextElement.Clone(): OpenXmlTextElement;virtual;
begin
obj := new OpenXmlTextElement(nil, {self.}Prefix, {self.}LocalName);
if not ifnil({self.}Text) then obj.Text := {self.}Text;
return obj;
end
function OpenXmlTextElement.Marshal(): tableArray;override; function OpenXmlTextElement.Marshal(): tableArray;override;
begin begin
arr := array("type": "element", "name": name_, "attributes": array(), "children": array()); arr := array("type": "element", "name": name_, "attributes": array(), "children": array());
@ -31,7 +40,7 @@ end;
function OpenXmlTextElement.Deserialize();override; function OpenXmlTextElement.Deserialize();override;
begin begin
if not ifObj({self.}XmlNode) then return; if deserialized_ or not ifObj({self.}XmlNode) then return;
{self.}Text := {self.}XmlNode.GetText(); {self.}Text := {self.}XmlNode.GetText();
attrs := {self.}XmlNode.Attributes(); attrs := {self.}XmlNode.Attributes();
for k, v in attrs do for k, v in attrs do
@ -46,6 +55,7 @@ begin
if ifnil(pf) then continue; if ifnil(pf) then continue;
pf.Do(v); pf.Do(v);
end end
deserialized_ := true;
end; end;
function OpenXmlTextElement.Serialize();override; function OpenXmlTextElement.Serialize();override;