202 lines
6.2 KiB
Plaintext
202 lines
6.2 KiB
Plaintext
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 Deserialize();
|
|
function Serialize();
|
|
function Marshal(): tableArray;
|
|
function GetOrCreateNode(_obj: tslobj);
|
|
function GetNode(): XmlNode;
|
|
function Elements(): array of tslobj;
|
|
function Attributes(): array of OpenXmlAttribute;
|
|
function Xmlns(_prefix: string): string;
|
|
|
|
public
|
|
function AppendChild(_obj: tslobj); // OpenXmlElement or OpenXmlPcdata
|
|
function InsertAfter(_obj: tslobj; _pos_obj: tslobj);
|
|
// function InsertBefore(_pos_obj: tslobj; _obj: tslobj);
|
|
// function PrependChild(_obj: tslobj);
|
|
// function RemoveChild(_obj: tslobj);
|
|
// function SetAttribute(_obj: OpenXmlAttribute);
|
|
|
|
public
|
|
LocalName: string; // 本地名称
|
|
[weakref]Parent: tslobj; // 父类
|
|
Prefix: string; // 前缀
|
|
XmlNode: XmlNode; // XMLNode节点
|
|
ElementName: string;
|
|
|
|
protected
|
|
attributes_: array of OpenXmlAttribute; // 属性
|
|
attributes_pf_: tableArray;
|
|
// child_elements_: array of tslobj; // 子节点元素
|
|
sorted_child_: tableArray;
|
|
container_: TSOfficeContainer;
|
|
xmlns_: 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);
|
|
xmlns_ := array();
|
|
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();
|
|
xmlns_ := array();
|
|
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;
|
|
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
|
|
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;
|
|
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_.Get();
|
|
for k, v in child_elements do
|
|
v.Deserialize();
|
|
end;
|
|
|
|
function OpenXmlElement.Serialize();
|
|
begin
|
|
// 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);
|
|
// Children
|
|
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
|
|
begin
|
|
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.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.Elements(): array of tslobj;
|
|
begin
|
|
return container_.Get();
|
|
end;
|
|
|
|
function OpenXmlElement.InsertAfter(_obj: tslobj; _pos_obj: tslobj);
|
|
begin
|
|
container_.InsertAfter(_obj, _pos_obj);
|
|
end;
|
|
|
|
function OpenXmlElement.AppendChild(_obj: tslobj);
|
|
begin
|
|
container_.Append(_obj);
|
|
end;
|