我似乎无法遍历以下XML文件。
<?xml version="1.0" encoding="utf-8"?>
<Screen>
<Title>MainMenuScrn</Title>
<Start>True</Start>
<BackColor>clBlue</BackColor>
<Orientation>orLandscape</Orientation>
<Image><none></Image>
<tTFTImage>
<Enabled>True</Enabled>
<Fixed>False</Fixed>
<Height>57</Height>
<Image>HeatIcon</Image>
<Left>40</Left>
<Name>Image1</Name>
<Parent>pnlScreenArea</Parent>
<Top>49</Top>
<Visible>True</Visible>
<Width>57</Width>
</tTFTImage>
<tTFTStaticLabel>
<Caption>Settings</Caption>
<Enabled>True</Enabled>
<Fixed>False</Fixed>
<FontColor>clWhite</FontColor>
<FontRef>BigBold</FontRef>
<Height>16</Height>
<Left>237</Left>
<Name>StaticLabel3</Name>
<Parent>pnlScreenArea</Parent>
<Top>207</Top>
<Visible>True</Visible>
<Width>51</Width>
</tTFTStaticLabel>
<tTFTContainer>
<BorderStyle>bsNone</BorderStyle>
<Caption></Caption>
<Color>clYellow</Color>
<Enabled>True</Enabled>
<Height>138</Height>
<Left>59</Left>
<Name>Container1</Name>
<Parent>pnlScreenArea</Parent>
<Top>58</Top>
<Visible>True</Visible>
<Width>202</Width>
<tTFTButton>
<Caption>Skip</Caption>
<Color>clSilver</Color>
<Enabled>True</Enabled>
<Fixed>False</Fixed>
<FontColor>clWindowText</FontColor>
<FontRef>BigBold</FontRef>
<Height>32</Height>
<Left>20</Left>
<Name>btnSkip</Name>
<OnClick>btnSkip_OnClick</OnClick>
<Parent>Container1</Parent>
<Pen>78650656<Color>clBlack</Color><Width>1</Width></Pen>
<PressColor>clBlack</PressColor>
<Rounded>False</Rounded>
<Top>97</Top>
<Transparent>False</Transparent>
<Visible>True</Visible>
<Width>64</Width>
</tTFTButton>
<tTFTStaticLabel>
<Caption>to set up or Skip to continue</Caption>
<Enabled>True</Enabled>
<Fixed>False</Fixed>
<FontColor>clWindowText</FontColor>
<FontRef>Default</FontRef>
<Height>16</Height>
<Left>18</Left>
<Name>StaticLabel6</Name>
<Parent>Container1</Parent>
<Top>52</Top>
<Visible>True</Visible>
<Width>164</Width>
</tTFTStaticLabel>
<tTFTButton>
<Caption>OK</Caption>
<Color>clSilver</Color>
<Enabled>True</Enabled>
<Fixed>False</Fixed>
<FontColor>clWindowText</FontColor>
<FontRef>BigBold</FontRef>
<Height>32</Height>
<Left>124</Left>
<Name>btnOK</Name>
<OnClick>btnSkip_OnPress</OnClick>
<Parent>Container1</Parent>
<Pen>78650432<Color>clBlack</Color><Width>1</Width></Pen>
<PressColor>clBlack</PressColor>
<Rounded>True</Rounded>
<Top>95</Top>
<Transparent>False</Transparent>
<Visible>True</Visible>
<Width>64</Width>
</tTFTButton>
<tTFTStaticLabel>
<Caption>since installation. Choose OK</Caption>
<Enabled>True</Enabled>
<Fixed>False</Fixed>
<FontColor>clWindowText</FontColor>
<FontRef>Default</FontRef>
<Height>16</Height>
<Left>18</Left>
<Name>StaticLabel5</Name>
<Parent>Container1</Parent>
<Top>34</Top>
<Visible>True</Visible>
<Width>172</Width>
</tTFTStaticLabel>
<tTFTStaticLabel>
<Caption>Controller has not been setup</Caption>
<Enabled>True</Enabled>
<Fixed>False</Fixed>
<FontColor>clWindowText</FontColor>
<FontRef>Default</FontRef>
<Height>16</Height>
<Left>18</Left>
<Name>StaticLabel4</Name>
<Parent>Container1</Parent>
<Top>17</Top>
<Visible>True</Visible>
<Width>170</Width>
</tTFTStaticLabel>
</tTFTContainer>
</Screen>
使用IXMLIntf和XMLDoc我编写了一个递归例程,它可以解决XMLNodes问题。一切正常,直到tTFTContainer下的第一个Object。我遍历从FirstSibling开始的节点并使用NextSibling进行循环,直到返回的Node为nil。当我到达tTFTButton时,NextSibling返回的节点实际上是tTFTButton(Caption)的第一个子节点。我无法接受元素tTFTButton。
我使用IsTextElement来确定Node是否携带属性。我假设IsTextElement返回false将停在tTFTButton,所以我可以使用这个Node传回我的例程。
这是常规....
function XMLToObject(ObjNode: IXMLNode;
Scrn: tfmWorkingScreen;
ParentCtrl: TWinControl): Boolean;
// Creates and Registers a TControl based on the XML definition of the object passed
// if object is a container all objects in that container will also be handled.
// Returns true if Object created and registered.
function IsEvent(NodeName: String): Boolean;
begin
Result := (NodeName = 'OnClick')
Or (NodeName = 'OnUp')
Or (NodeName = 'OnPress')
Or (NodeName = 'OnDown');
end;
Procedure SetPropVal(PropName: String; PropVal: String); //OleVariant);
begin
ObjProps.FindProperty(PropName).AsString := PropVal;
end;
Var PropNode, SubNode: IXMLNode;
ObjIdx: Integer;
s: String;
begin
Result := Assigned(ObjNode);
if Assigned(ObjNode) then begin
ObjIdx := IndexOfObject(ObjNode.NodeName); // Index into Objects list
if (ObjIdx > -1) and (ObjIdx < ObjCount) then begin
PropNode := ObjNode.ChildNodes.FindNode('Name');
ObjProps.Instance := CreateObj(PropNode.NodeValue,ObjIdx, Scrn, ParentCtrl);
Scrn.RegisterAndAssign(TControl(ObjProps.Instance)); // register object to Screen
Result := Assigned(ObjProps.Instance); //
if not result then begin
PropNode := ObjNode.ChildNodes.First;
while Assigned(PropNode) do begin
if (PropNode.IsTextElement) then begin // if it is a property (Assumes Pen has propvalue)
// This should also be done recursively
if PropNode.ChildNodes.Count > 1 then begin // if it has child properties
SubNode := PropNode.ChildNodes.First;
while Assigned(SubNode) do begin
s := PropNode.NodeName + '.' + SubNode.NodeName;
ObjProps.FindProperty(s).AsString := subNode.NodeValue;
SubNode := SubNode.NextSibling;
end;
end
else
if IsEvent(PropNode.NodeName) then // Set up the events
Scrn.SetEventVal(ObjProps.Instance.Name, PropNode.NodeName, PropNode.Text);
ObjProps.FindProperty(PropNode.NodeName).AsString := PropNode.NodeValue; // Set property value
end
else
begin
SubNode := PropNode;
while Assigned(SubNode) do begin
ShowMessage(SubNode.NodeName + ' ' + IntToStr(PropNode.ParentNode.ChildNodes.Count) + ' ' + PropNode.Text); // Debug
Result := XMLToObject(SubNode, Scrn, TWinControl(ObjProps.Instance)); // recurse through container objects
if Result then
SubNode := SubNode.NextSibling
else
break;
end;
end;
if Not Result then Break; // Get out if error
PropNode := PropNode.NextSibling; // move on to next item
end;
end;
end;
end;
end;
这就是它的调用方式。 PropNode是第一个携带对象信息的XML节点....
while Assigned(PropNode) do begin
if XMLToObject(PropNode, WorkScrn, WorkScrn.pnlScreenArea) then
PropNode := PropNode.NextSibling
else
begin
MessageDlg('Unable to process ' + PropNode.NodeName + ' in ' + fFileName,
mtWarning, [mbOK], 0);
break;
end;
end;
这是完整的XML文件......
我希望一切都有道理。我不确定我是否正确使用XML,我正在尝试制作文本DMF文件的XML版本。