利用nil新特性进行性能优化
This commit is contained in:
+57
-119
@@ -3,8 +3,6 @@ public
|
||||
function Create(_node: XmlNode);overload;
|
||||
function Create(_parent: tslobj; _prefix: string; _local_name: string);overload;
|
||||
function Init();virtual;
|
||||
function InitAttributes();virtual;
|
||||
function InitChildren();virtual;
|
||||
function InitNode(_node: XmlNode);virtual;
|
||||
function Copy(_obj: tslobj);virtual;
|
||||
|
||||
@@ -13,20 +11,22 @@ public
|
||||
function Marshal(): tableArray;
|
||||
function GetOrCreateNode(_obj: tslobj);
|
||||
function GetNode(): XmlNode;
|
||||
|
||||
// 增删改查接口
|
||||
function Append(_obj: tslobj): boolean; // OpenXmlElement or OpenXmlPcdata
|
||||
function InsertAfter(_pos_obj: tslobj; _obj: tslobj): boolean;
|
||||
function InsertBefore(_pos_obj: tslobj; _obj: tslobj): boolean;
|
||||
function Prepend(var _obj: tslobj): boolean;
|
||||
function Remove(_obj: tslobj): boolean;
|
||||
function AddAttribute(_obj: OpenXmlAttribute): boolean;
|
||||
function Elements(): array of tslobj;
|
||||
function Attributes(): array of OpenXmlAttribute;
|
||||
|
||||
protected
|
||||
function IsValidChild(_obj: tslobj);
|
||||
function FindChild(_obj: tslobj);
|
||||
function InsertChild(_obj: tslobj; _pos: integer);
|
||||
// 增删改查接口 -- 暂不实现
|
||||
// public
|
||||
// function Append(_obj: tslobj): boolean; // OpenXmlElement or OpenXmlPcdata
|
||||
// function InsertAfter(_pos_obj: tslobj; _obj: tslobj): boolean;
|
||||
// function InsertBefore(_pos_obj: tslobj; _obj: tslobj): boolean;
|
||||
// function Prepend(var _obj: tslobj): boolean;
|
||||
// function Remove(_obj: tslobj): boolean;
|
||||
// function AddAttribute(_obj: OpenXmlAttribute): boolean;
|
||||
|
||||
// protected
|
||||
// function IsValidChild(_obj: tslobj);
|
||||
// function FindChild(_obj: tslobj);
|
||||
// function InsertChild(_obj: tslobj; _pos: integer);
|
||||
|
||||
public
|
||||
LocalName: string; // 本地名称
|
||||
@@ -37,8 +37,10 @@ public
|
||||
|
||||
protected
|
||||
attributes_: array of OpenXmlAttribute; // 属性
|
||||
child_elements_: array of tslobj; // 子节点元素
|
||||
attributes_pf_: tableArray;
|
||||
// child_elements_: array of tslobj; // 子节点元素
|
||||
sorted_child_: tableArray;
|
||||
container_: TSOfficeContainer;
|
||||
end;
|
||||
|
||||
function OpenXmlElement.Create(_node: XmlNode);overload;
|
||||
@@ -58,15 +60,36 @@ begin
|
||||
{self.}XmlNode := nil;
|
||||
{self.}ElementName := ifString({self.}Prefix) and {self.}Prefix <> "" ? format("%s:%s", {self.}Prefix, {self.}LocalName) : {self.}LocalName;
|
||||
{self.}Init();
|
||||
{self.}InitAttributes();
|
||||
{self.}InitChildren();
|
||||
end;
|
||||
|
||||
function OpenXmlElement.InitNode(_node: XmlNode);virtual;
|
||||
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 OpenXmlElement.GetOrCreateNode(_obj: tslobj);
|
||||
begin
|
||||
if not ifObj({self.}XmlNode) then {self.}XmlNode := {self.}Parent.GetOrCreateNode(self);
|
||||
nearest_node := nil;
|
||||
for k, v in child_elements_ do
|
||||
child_elements := container_.Get();
|
||||
for k, v in child_elements do
|
||||
begin
|
||||
if ifObj(v.XmlNode) then nearest_node := v.XmlNode;
|
||||
if v = _obj then
|
||||
@@ -87,13 +110,16 @@ end;
|
||||
|
||||
function OpenXmlElement.Deserialize();
|
||||
begin
|
||||
if not ifObj({self.}XmlNode) then return nil;
|
||||
for k, v in attributes_ do
|
||||
if not ifObj({self.}XmlNode) then return;
|
||||
attrs := {self.}XmlNode.Attributes();
|
||||
for k, v in attrs do
|
||||
begin
|
||||
attr := {self.}XmlNode.GetAttribute(v.ElementName);
|
||||
v.Value := attr = "" ? nil : attr;
|
||||
pf := attributes_pf_[k];
|
||||
if ifnil(pf) then continue;
|
||||
pf.Do(v);
|
||||
end
|
||||
for k, v in child_elements_ do
|
||||
child_elements := container_.Get();
|
||||
for k, v in child_elements do
|
||||
v.Deserialize();
|
||||
end;
|
||||
|
||||
@@ -103,16 +129,17 @@ begin
|
||||
for k, v in attributes_ do
|
||||
if not ifnil(v.Value) then {self.}GetNode().SetAttribute(v.ElementName, v.Value);
|
||||
// Children
|
||||
for k, v in child_elements_ do
|
||||
if ifObj(v) then v.Serialize();
|
||||
child_elements := container_.Get();
|
||||
for k, v in child_elements do
|
||||
v.Serialize();
|
||||
end;
|
||||
|
||||
function OpenXmlElement.Marshal(): tableArray;
|
||||
begin
|
||||
child_elements := container_.Get();
|
||||
child_arr := array();
|
||||
for k, v in child_elements_ do
|
||||
for k, v in child_elements do
|
||||
begin
|
||||
if ifnil(v) then continue;
|
||||
arr := array("type": "element", "name": v.ElementName, "attributes": array());
|
||||
if v is Class(OpenXmlPcdata) or v is Class(OpenXmlElement) then
|
||||
begin
|
||||
@@ -128,7 +155,7 @@ begin
|
||||
if length(marshal) > 0 then child_arr[length(child_arr)] := arr;
|
||||
end
|
||||
else begin
|
||||
echo "error = marshal,\n";
|
||||
echo "error = marshal.\n";
|
||||
end
|
||||
end
|
||||
|
||||
@@ -140,97 +167,8 @@ begin
|
||||
return tmp_arr;
|
||||
end;
|
||||
|
||||
function OpenXmlElement.Append(_obj: tslobj): boolean; // OpenXmlElement or OpenXmlPcdata
|
||||
begin
|
||||
if not {self.}IsValidChild(_obj) then return false;
|
||||
_obj.Parent := self;
|
||||
child_elements_[length(child_elements_)] := _obj;
|
||||
// _obj := nil;
|
||||
return true;
|
||||
end;
|
||||
|
||||
function OpenXmlElement.InsertAfter(_pos_obj: tslobj; _obj: tslobj): boolean;
|
||||
begin
|
||||
if not {self.}IsValidChild(_pos_obj) or not {self.}IsValidChild(_obj) then return false;
|
||||
find_pos := {self.}FindChild(_pos_obj);
|
||||
if find_pos = -1 then return false;
|
||||
{self.}InsertChild(_obj, find_pos);
|
||||
return true;
|
||||
end;
|
||||
|
||||
function OpenXmlElement.InsertBefore(_pos_obj: tslobj; _obj: tslobj): boolean;
|
||||
begin
|
||||
if not {self.}IsValidChild(_pos_obj) or not {self.}IsValidChild(_obj) then return false;
|
||||
find_pos := {self.}FindChild(_pos_obj);
|
||||
if find_pos = -1 then return false;
|
||||
{self.}InsertChild(_obj, find_pos-1);
|
||||
return true;
|
||||
end;
|
||||
|
||||
function OpenXmlElement.Prepend(_obj: tslobj): boolean;
|
||||
begin
|
||||
if not {self.}IsValidChild(_pos_obj) or not {self.}IsValidChild(_obj) then return false;
|
||||
{self.}InsertChild(_obj, 0);
|
||||
return true;
|
||||
end;
|
||||
|
||||
function OpenXmlElement.Remove(_obj: tslobj): boolean;
|
||||
begin
|
||||
if ifnil(_obj)then // 删除所有
|
||||
begin
|
||||
if not ifObj({self.}XmlNode) or not ifObj({self.}Parent) or not ifObj({self.}PartName.XmlNode) then return false;
|
||||
{self.}Parent.XmlNode.DeleteChild({self.}XmlNode);
|
||||
return true;
|
||||
end
|
||||
else if {self.}IsValidChild(_obj) then
|
||||
begin
|
||||
if not ifObj(_obj.XmlNode) or not ifObj({self.}XmlNode) then return false;
|
||||
{self.}XmlNode.DeleteChild(_obj.XmlNode);
|
||||
return true;
|
||||
end
|
||||
else if _obj is Class(OpenXmlAttribute) then
|
||||
begin
|
||||
if not ifObj({self.}XmlNode) then return false;
|
||||
{self.}XmlNode.DeleteAttribute(_obj.ElementName);
|
||||
return false;
|
||||
end
|
||||
end;
|
||||
|
||||
function OpenXmlElement.AddAttribute(_obj: OpenXmlAttribute): boolean;
|
||||
begin
|
||||
if not _obj is Class(OpenXmlAttribute) then return false;
|
||||
attributes_[length(attributes_)] := _obj;
|
||||
return true;
|
||||
end;
|
||||
|
||||
function OpenXmlElement.InsertChild(_obj: tslobj; _pos: integer);
|
||||
begin
|
||||
for i:=length(child_elements_)-1 downto _pos do
|
||||
child_elements_[i+1] := child_elements_[i];
|
||||
_obj.Parent := self;
|
||||
child_elements_[_pos] := _obj;
|
||||
end;
|
||||
|
||||
function OpenXmlElement.IsValidChild(_obj: tslobj): boolean;
|
||||
begin
|
||||
return _obj is Class(OpenXmlPcdata) or _obj is Class(OpenXmlElement) ? true : false;
|
||||
end;
|
||||
|
||||
function OpenXmlElement.FindChild(_obj: tslobj);
|
||||
begin
|
||||
not_found := true;
|
||||
for k,v in child_elements_ do
|
||||
begin
|
||||
if v = _obj then
|
||||
begin
|
||||
not_found := false;
|
||||
break;
|
||||
end
|
||||
end
|
||||
return not_found ? -1 : k;
|
||||
end;
|
||||
|
||||
function OpenXmlElement.Elements(): array of tslobj;
|
||||
begin
|
||||
return child_elements_;
|
||||
return container_.Get();
|
||||
end;
|
||||
|
||||
|
||||
+31
-20
@@ -2,15 +2,22 @@ type OpenXmlEmpty = class
|
||||
public
|
||||
function Create(_node: XmlNode);overload;
|
||||
function Create(_parent: tslobj; _prefix: string; _local_name: string);overload;
|
||||
function Init();
|
||||
function InitNode(_node: XmlNode);
|
||||
|
||||
function Copy(_obj: tslobj);virtual;
|
||||
function GetNode(): XmlNode;
|
||||
function Marshal(): tableArray;
|
||||
function BoolValue(): boolean;
|
||||
function Deserialize();
|
||||
function Serialize();
|
||||
|
||||
public
|
||||
// attributes property
|
||||
XmlAttrVal;
|
||||
property Val read ReadXmlAttrVal write WriteXmlAttrVal;
|
||||
function ReadXmlAttrVal();
|
||||
function WriteXmlAttrVal(_value: any);
|
||||
|
||||
public
|
||||
LocalName: string; // 本地名称
|
||||
[weakref]Parent: tslobj; // 父类
|
||||
@@ -19,11 +26,6 @@ public
|
||||
ElementName: string;
|
||||
Value: any;
|
||||
|
||||
public
|
||||
XmlAttrVal;
|
||||
property Val read ReadXmlAttrVal write WriteXmlAttrVal;
|
||||
function ReadXmlAttrVal();
|
||||
function WriteXmlAttrVal(_value: any);
|
||||
end;
|
||||
|
||||
function OpenXmlEmpty.Create(_node: XmlNode);overload;
|
||||
@@ -42,14 +44,8 @@ begin
|
||||
{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.}Init();
|
||||
end;
|
||||
|
||||
function OpenXmlEmpty.Init();
|
||||
begin
|
||||
{self.}XmlAttrVal := new OpenXmlAttribute({self.}Prefix, "val", nil);
|
||||
end
|
||||
|
||||
function OpenXmlEmpty.InitNode(_node: XmlNode);
|
||||
begin
|
||||
{self.}XmlNode := ifObj(_node) ? _node : nil;
|
||||
@@ -58,7 +54,7 @@ end;
|
||||
function OpenXmlEmpty.Copy(_obj: tslobj);
|
||||
begin
|
||||
if not ifnil(_obj.Value) then {self.}Value := _obj.Value;
|
||||
if not ifnil(_obj.XmlAttrVal.Value) then {self.}XmlAttrVal.Value := _obj.XmlAttrVal.Value;
|
||||
if not ifnil(_obj.XmlAttrVal.Value) then {self.}Val := _obj.XmlAttrVal.Value;
|
||||
end;
|
||||
|
||||
function OpenXmlEmpty.Marshal(): tableArray;
|
||||
@@ -74,13 +70,16 @@ function OpenXmlEmpty.Deserialize();
|
||||
begin
|
||||
if ifObj({self.}XmlNode) then
|
||||
begin
|
||||
v := {self.}XmlNode.GetAttribute({self.}XmlAttrVal.ElementName);
|
||||
{self.}Value := v = "0" ? false : true;
|
||||
{self.}XmlAttrVal.Value := v = "" ? nil : v;
|
||||
attrs := {self.}XmlNode.Attributes();
|
||||
if length(attrs) > 1 then raise "OpenXmlEmpty.Deserialize error.\n";
|
||||
{self.}Val := nil;
|
||||
for k,v in attrs do
|
||||
{self.}Val := v;
|
||||
{self.}Value := ifnil({self.}Val) ? true : {self.}Val = "0" ? false : true;
|
||||
end
|
||||
else begin
|
||||
{self.}Value := nil;
|
||||
{self.}XmlAttrVal.Value := nil;
|
||||
{self.}XmlAttrVal := nil;
|
||||
end
|
||||
end;
|
||||
|
||||
@@ -92,9 +91,19 @@ end;
|
||||
|
||||
function OpenXmlEmpty.Serialize();
|
||||
begin
|
||||
if not ifObj({self.}XmlNode) and not {self.}Value then return;
|
||||
if ifObj({self.}XmlNode) and not {self.}Value and ifObj({self.}Parent) and ifObj({self.}Parent.XmlNode) then {self.}Parent.XmlNode.DeleteChild({self.}XmlNode);
|
||||
if not ifObj({self.}XmlNode) and {self.}Value then {self.}GetNode();
|
||||
if not ifObj({self.}XmlNode) then
|
||||
begin
|
||||
if not ifnil({self.}XmlAttrVal.Value) then {self.}GetNode().SetAttribute({self.}XmlAttrVal.ElementName, {self.}XmlAttrVal.Value);
|
||||
end
|
||||
else begin
|
||||
if not ifnil({self.}XmlAttrVal.Value) then {self.}XmlNode.SetAttribute({self.}XmlAttrVal.ElementName, {self.}XmlAttrVal.Value);
|
||||
else if not {self.}Value and ifObj({self.}Parent.XmlNode) then{self.}Parent.XmlNode.DeleteChild({self.}XmlNode);
|
||||
end
|
||||
end;
|
||||
|
||||
function OpenXmlEmpty.BoolValue(): boolean;
|
||||
begin
|
||||
return ifnil({self.}Val) ? {self.}Value : {self.}Val;
|
||||
end;
|
||||
|
||||
function OpenXmlEmpty.ReadXmlAttrVal();
|
||||
@@ -104,5 +113,7 @@ end;
|
||||
|
||||
function OpenXmlEmpty.WriteXmlAttrVal(_value: any);
|
||||
begin
|
||||
if ifnil({self.}XmlAttrVal) then
|
||||
{self.}XmlAttrVal := new OpenXmlAttribute({self.}Prefix, "val", nil);
|
||||
{self.}XmlAttrVal.Value := _value;
|
||||
end;
|
||||
|
||||
@@ -3,7 +3,6 @@ public
|
||||
function Create(_node: XmlNode);overload;
|
||||
function Create(_parent: tslobj; _prefix: string; _local_name: string);overload;
|
||||
function Init();virtual;
|
||||
function InitAttributes();virtual;
|
||||
function InitNode(_node: XmlNode);virtual;
|
||||
|
||||
function Copy(_obj: tslobj);virtual;
|
||||
@@ -22,6 +21,7 @@ public
|
||||
|
||||
protected
|
||||
attributes_: array of OpenXmlAttribute; // 属性
|
||||
attributes_pf_: tableArray;
|
||||
|
||||
end;
|
||||
|
||||
@@ -43,7 +43,6 @@ begin
|
||||
{self.}Text := nil;
|
||||
{self.}ElementName := ifString({self.}Prefix) and {self.}Prefix <> "" ? format("%s:%s", {self.}Prefix, {self.}LocalName) : {self.}LocalName;
|
||||
{self.}Init();
|
||||
{self.}InitAttributes();
|
||||
end;
|
||||
|
||||
function OpenXmlPcdata.InitNode(_node: XmlNode);virtual;
|
||||
@@ -62,9 +61,15 @@ end;
|
||||
|
||||
function OpenXmlPcdata.Deserialize();
|
||||
begin
|
||||
{self.}Text := ifObj({self.}XmlNode) ? {self.}XmlNode.GetText() : nil;
|
||||
for k,v in attributes_ do
|
||||
v.Value := ifObj({self.}XmlNode) ? {self.}XmlNode.GetAttribute(v.ElementName) : nil;
|
||||
if not ifObj({self.}XmlNode) then return;
|
||||
{self.}Text := {self.}XmlNode.GetText();
|
||||
attrs := {self.}XmlNode.Attributes();
|
||||
for k, v in attrs do
|
||||
begin
|
||||
pf := attributes_pf_[k];
|
||||
if ifnil(pf) then continue;
|
||||
pf.Do(v);
|
||||
end
|
||||
end;
|
||||
|
||||
function OpenXmlPcdata.GetNode(): XmlNode;
|
||||
|
||||
Reference in New Issue
Block a user