This commit is contained in:
csh
2024-06-25 16:19:20 +08:00
parent ac62594901
commit d244a95fb2
478 changed files with 46805 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
type OpenXmlAttribute = class
public
function Create(_prefix: string; _local_name: string);overload;
function Create(_prefix: string; _local_name: string; _value: any);overload;
public
LocalName: string;
Prefix: tslobj;
ElementName: string;
Value: any;
end;
function OpenXmlAttribute.Create(_prefix: string; _local_name: string);overload;
begin
self.Create(_prefix, _local_name, nil);
end;
function OpenXmlAttribute.Create(_prefix: string; _local_name: string; _value: any);overload;
begin
self.Prefix := _prefix;
self.LocalName := _local_name;
self.Value := _value;
self.ElementName := ifString(self.Prefix) and self.Prefix <> "" ? format("%s:%s", self.Prefix, self.LocalName) : self.LocalName;
end;
+236
View File
@@ -0,0 +1,236 @@
type OpenXmlElement = class
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;
function Deserialize();
function Serialize();
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;
protected
function IsValidChild(_obj: tslobj);
function FindChild(_obj: tslobj);
function InsertChild(_obj: tslobj; _pos: integer);
public
LocalName: string; // 本地名称
[weakref]Parent: tslobj; // 父类
Prefix: tslobj; // 前缀
XmlNode: XmlNode; // XMLNode节点
ElementName: string;
protected
attributes_: tableArray; // 属性
child_elements_: array of tslobj; // 子节点元素
sorted_child_: tableArray;
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.Init();
self.InitAttributes();
self.InitChildren();
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
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 OpenXmlElement.GetNode(): XmlNode;
begin
if not ifObj(self.XmlNode) then self.XmlNode := self.Parent.GetOrCreateNode(self);
return self.XmlNode;
end;
function OpenXmlElement.Deserialize();
begin
if not ifObj(self.XmlNode) then return nil;
for k, v in attributes_ do
begin
attr := self.XmlNode.GetAttribute(v.ElementName);
v.Value := attr = "" ? nil : attr;
end
for k, v in child_elements_ do
v.Deserialize();
end;
function OpenXmlElement.Serialize();
begin
// Attributes
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();
end;
function OpenXmlElement.Marshal(): tableArray;
begin
child_arr := array();
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
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(OpenXmlEmpty) 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 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_;
end;
+107
View File
@@ -0,0 +1,107 @@
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 Deserialize();
function Serialize();
public
LocalName: string; // 本地名称
Parent: tslobj; // 父类
[weakref]Prefix: tslobj; // 前缀
XmlNode: XmlNode; // XMLNode节点
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;
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 OpenXmlEmpty.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.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;
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;
end;
function OpenXmlEmpty.Marshal(): tableArray;
begin
if not self.Value then return array();
attr := array();
if not inil(self.XmlAttrVal.Value) then attr[self.XmlAttrVal.ElementName] := self.XmlAttrVal.Value;
arr := array("type": "element", "name": name_, "attributes": attr, "children": array());
return arr;
end;
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;
end
else begin
self.Value := nil;
end
end;
function OpenXmlEmpty.GetNode(): XmlNode;
begin
if not ifObj(self.XmlNode) then self.XmlNode := self.Parent.GetOrCreateNode(self);
return self.XmlNode;
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();
end;
function OpenXmlEmpty.ReadXmlAttrVal();
begin
return self.XmlAttrVal.Value;
end;
function OpenXmlEmpty.WriteXmlAttrVal(_value: any);
begin
self.XmlAttrVal.Value := _value;
end;
+82
View File
@@ -0,0 +1,82 @@
type OpenXmlPcdata = class
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;
function GetNode(): XmlNode;
function Marshal(): tableArray;
function Deserialize();
function Serialize();
public
LocalName: string; // 本地名称
[weakref]Parent: tslobj; // 父类
Prefix: tslobj; // 前缀
XmlNode: XmlNode; // XMLNode节点
ElementName: string;
Text: string; // 元素的文本内容,有的话就是pcdata,没有就是普通的节点
protected
attributes_: tableArray; // 不提供访问
end;
function OpenXmlPcdata.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 OpenXmlPcdata.Create(_parent: tslobj; _prefix: string; _local_name: string);overload;
begin
self.Parent := _parent;
self.Prefix := _prefix;
self.LocalName := _local_name;
self.XmlNode := nil;
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;
begin
self.XmlNode := ifObj(_node) ? _node : nil;
end;
function OpenXmlPcdata.Marshal(): tableArray;
begin
arr := array("type": "element", "name": name_, "attributes": array(), "children": array());
for k,v in attributes_ do
if not ifnil(v.Value) then arr["attributes"][v.ElementName] := v.Value;
if not ifnil(self.Text) then arr["children"] := array(("type": "pcdata", "value": self.Text));
return arr;
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;
end;
function OpenXmlPcdata.GetNode(): XmlNode;
begin
if not ifObj(self.XmlNode) then self.XmlNode := self.Parent.GetOrCreateNode(self);
return self.XmlNode;
end;
function OpenXmlPcdata.Serialize();
begin
if not ifnil(self.Text) then self.GetNode().SetValue(self.Text);
for k,v in attributes_ do
if not ifnil(v.Value) then self.GetNode().SetAttribute(v.ElementName, v.Value);
end;