277 lines
6.9 KiB
Plaintext
277 lines
6.9 KiB
Plaintext
Type NodeInfo = class
|
||
|
||
public
|
||
Function Create(p, name);
|
||
Begin
|
||
if ifObj(p) then
|
||
NodeUri := p.NodeUri = '' ? name : (p.NodeUri + '/' + name);
|
||
else
|
||
NodeUri := '';
|
||
NodeName := name;
|
||
ExtAttr := array();
|
||
ExtNodes := array();
|
||
ReplaceArr := array();
|
||
End
|
||
|
||
Function Root(); virtual;
|
||
Begin
|
||
return RootObj;
|
||
End
|
||
|
||
Function Update();
|
||
Begin
|
||
if ifObj(RootObj) then Begin
|
||
arr := Marshal();
|
||
if length(arr['attributes']) or length(arr['children']) then Begin
|
||
curNode := class(TSXml).GetNode(RootObj, NodeUri);
|
||
if ifObj(curNode) then
|
||
class(TSXml).UpdateNode(curNode, arr['attributes'], arr['children']);
|
||
End;
|
||
End;
|
||
End;
|
||
|
||
Function HandleAttrs(); virtual;
|
||
Begin
|
||
End
|
||
|
||
Function HandleChildren(); virtual;
|
||
Begin
|
||
End
|
||
|
||
Function GetAttrs(); virtual;
|
||
Begin
|
||
return ExtAttr;
|
||
End
|
||
|
||
Function GetChildren(); virtual;
|
||
Begin
|
||
return ExtNodes;
|
||
End
|
||
|
||
Function GetNode(index); // 返回的index的对象
|
||
Begin
|
||
return ExtNodes[index]['obj'];
|
||
End
|
||
|
||
Function GetCount(); // 返回当前节点的个数
|
||
Begin
|
||
return length(ExtAttr);
|
||
End
|
||
|
||
// arr := array(('Size', 'sz', 15), ('Style', 'style', 'line'));
|
||
Function AddAttr(arr); // 添加属性
|
||
Begin
|
||
if not istable(arr) then return;
|
||
ExtAttr union= arr;
|
||
return 1;
|
||
End
|
||
|
||
Function Marshal();
|
||
Begin
|
||
children_ := nil;
|
||
GetChildrenEx(); //优化为变量,减少数据COPY,2022-12-10
|
||
child_arr := array();
|
||
len := 0;
|
||
for i:=0 to length(children_)-1 do
|
||
begin
|
||
node_type := children_[i]['nodeType'];
|
||
obj := children_[i]['obj'];
|
||
if ifnil(obj) then continue;
|
||
//find := select thisrowindex as "rowindex_", * from child_arr where ['name'] = children_[i]['name'] end; //优化为循环,性能提高15-20%,2022-12-20
|
||
find := array();
|
||
for j:=length(child_arr)-1 downto 0 do Begin //支持列表模式(如多节点:<w:t xml:space=""></w:t>),查找最近的节点
|
||
if child_arr[j]['name'] = children_[i]['name'] then Begin
|
||
find[0] := child_arr[j];
|
||
find[0]['rowindex_'] := j;
|
||
break;
|
||
End;
|
||
End;
|
||
if not ifnil(obj) and not ifObj(obj) and istable(find) and ifstring(children_[i]['attrEx']) and children_[i]['attrEx'] <> '' then
|
||
begin
|
||
if not ifarray(find[0]['attributes']) then find[0]['attributes'] := array();
|
||
key := children_[i]['attrEx'];
|
||
find[0]['attributes'] union= array(key : obj);
|
||
child_arr[find[0]['rowindex_']]['attributes'] := find[0]['attributes'];
|
||
continue;
|
||
end
|
||
|
||
arr := array('type': 'element', 'name': children_[i]['name'], 'attributes': array());
|
||
if node_type = 'empty' then // <b/>
|
||
begin
|
||
if obj = 0 then arr['attributes'] := array('val': 0);
|
||
else if obj = 1 then arr['attributes'] := array('val': 1)
|
||
end
|
||
else if node_type = 'pcdata' then
|
||
begin
|
||
arr['children'] := array(('type': 'pcdata', 'value': obj));
|
||
end
|
||
else if ifObj(obj) then
|
||
begin
|
||
marshal := obj.Marshal();
|
||
if length(marshal['children'])=0 and length(marshal['attributes'])=0 then continue;
|
||
arr['children'] := marshal['children'];
|
||
arr['attributes'] union= marshal['attributes'];
|
||
end
|
||
else
|
||
begin
|
||
key := children_[i]['attrName'] ? children_[i]['attrName'] : children_[i]['attrEx'] ? children_[i]['attrEx'] : 'val';
|
||
arr['attributes'] := array(key : obj);
|
||
end
|
||
|
||
child_arr[len++] := arr;
|
||
end
|
||
|
||
name_arr := str2array(NodeName, '/');
|
||
tmp_arr := array('type': 'element', 'name': name_arr[length(name_arr)-1], 'children': child_arr);
|
||
for i:=length(name_arr)-2 downto 0 do
|
||
begin
|
||
tmp_arr := array('type': 'element', 'name': name_arr[i], 'children': array(tmp_arr));
|
||
end
|
||
|
||
attrs_arr := GetAttrs();
|
||
tmp_arr['attributes'] := array();
|
||
for i:=0 to length(attrs_arr)-1 do
|
||
begin
|
||
if not ifnil(attrs_arr[i, 2]) then Begin
|
||
tmp_arr['attributes'][ attrs_arr[i, 1] ] := attrs_arr[i, 2];
|
||
End;
|
||
end
|
||
return tmp_arr;
|
||
End
|
||
|
||
Function NewChildNode(nodeArr);
|
||
Begin
|
||
if not ifarray(nodeArr) then return 0;
|
||
if not ifstring(nodeArr['name']) then return 0;
|
||
arr := array((
|
||
'name': nodeArr['name'],
|
||
'obj': nodeArr['obj'],
|
||
'attrEx': nodeArr['attrEx'],
|
||
'nodeType': nodeArr['nodeType'],
|
||
));
|
||
ExtNodes union= arr;
|
||
return 1;
|
||
End
|
||
|
||
Function Value(name);
|
||
Begin
|
||
if not ifObj(RootObj) then return nil;
|
||
if NodeUri <> '' then
|
||
node := class(TSXml).GetNode(RootObj, NodeUri);
|
||
else
|
||
node := RootObj;
|
||
if not ifObj(node) then return nil;
|
||
|
||
attrs := GetAttrsEx();
|
||
lName := lowerCase(name);
|
||
r := sselect * from attrs where lName = lowerCase([0]) end;
|
||
if istable(r) then
|
||
begin
|
||
value := node.GetAttribute(r[1]);
|
||
return trystrtofloat(value, r) ? r : value;
|
||
end
|
||
|
||
children := GetChildren();
|
||
r := select * from children where lName = lowerCase(['field']) end;
|
||
if istable(r) then Begin
|
||
r := r[0];
|
||
node := node.FirstChildElement(r['name']);
|
||
if not ifObj(node) and r['nodeType'] = 'empty' then return false;
|
||
if not ifObj(node) then return nil;
|
||
if r['nodeType'] = 'pcdata' then //返回文本串
|
||
return node.GetText();
|
||
if ifObj(r['obj']) then //对象,返回XML串
|
||
return node.Data();
|
||
key := r['attrName'] ? r['attrName'] : r['attrEx'] ? r['attrEx'] : 'val';
|
||
value := node.GetAttribute(key);
|
||
if r['nodeType'] = 'empty' and value = '' then return true;
|
||
return trystrtofloat(value, r) ? r : value;
|
||
End;
|
||
return nil;
|
||
End;
|
||
|
||
Function Replace(hash, bChild);
|
||
Begin
|
||
if istable(hash) then Begin
|
||
ReplaceArr := hash;
|
||
replaceNodeName();
|
||
if bChild then Begin
|
||
r := GetChildren();
|
||
for i:=0 to length(r)-1 do Begin
|
||
if ifObj(r[i]['obj']) then
|
||
r[i]['obj'].Replace(hash, bChild);
|
||
End;
|
||
End;
|
||
End;
|
||
End
|
||
|
||
Function GetChildrenEx();
|
||
Begin
|
||
if not ifarray(children_) then Begin
|
||
children_ := getChildren();
|
||
if not istable(ReplaceArr) then Begin
|
||
for i:=0 to length(children_)-1 do Begin
|
||
if ifarray(children_[i]['obj']) then Begin
|
||
if istable(children_[i]['obj']) then
|
||
hasArr := 1;
|
||
else
|
||
children_[i]['obj'] := nil;
|
||
End;
|
||
End;
|
||
End;
|
||
if hasArr or istable(ReplaceArr) then Begin
|
||
a := array();
|
||
for i:=0 to length(children_)-1 do Begin
|
||
if istable(ReplaceArr) then
|
||
children_[i]['name'] := ReplaceName(children_[i]['name']);
|
||
if istable(children_[i]['obj']) then Begin
|
||
a union= children_[i]['obj'];
|
||
End
|
||
else
|
||
a[ length(a) ] := children_[i];
|
||
end;
|
||
children_ := a;
|
||
End;
|
||
End;
|
||
End;
|
||
|
||
Function GetAttrsEx();
|
||
Begin
|
||
return GetAttrs();//暂时没有发现需要更新属性前缀的情况
|
||
if not istable(ReplaceArr) then return GetAttrs();
|
||
attr := GetAttrs();
|
||
for i:=0 to length(attr)-1 do
|
||
attr[i][1] := ReplaceName(attr[i][1]);
|
||
return attr;
|
||
End
|
||
|
||
private
|
||
Function replaceNodeName();
|
||
Begin
|
||
for k, v in ReplaceArr do
|
||
begin
|
||
NodeName := ReplaceStr(NodeName, k, v);
|
||
end
|
||
End
|
||
|
||
Function ReplaceName(name);
|
||
Begin
|
||
for k,v in ReplaceArr do Begin
|
||
if k='' then
|
||
name := v + name;
|
||
else
|
||
name := ReplaceStr(name, k, v);
|
||
End;
|
||
return name;
|
||
End;
|
||
public
|
||
NodeName;
|
||
ExtAttr;
|
||
ExtNodes;
|
||
//Parent;
|
||
ReplaceArr;
|
||
RootObj;
|
||
NodeUri:string;
|
||
children_;
|
||
End
|