{-----------------------------------------
创建XML文档,以及节点
------------------------------------------}
procedure TForm1.CreateXMLClick(Sender: TObject);
var
  pNode,cNode: IXMLNode;                   {定义两个节点: 父节点、子节点}
begin
  xmldcmnt1.XML.Clear;
  xmldcmnt1.Active := True;                {必须先激活}
  xmldcmnt1.Version := '1.0';              {设置版本}
  xmldcmnt1.Encoding := 'GB2312';          {设置语言}

  pNode := xmldcmnt1.AddChild('科室名单'); {添加的第一个节点是根节点, 现在的 pNode 是根节点}
  pNode.SetAttribute('备注', '测试');      {为根节点设置属性}

  pNode := pNode.AddChild('人员');         {为根节点添加子节点, 现在的 pNode 是 "人员" 节点}
  pNode.SetAttribute('职务', '科长');      {设置属性}
  pNode.SetAttribute('备注', '正局级');

  cNode := pNode.AddChild('姓名');          {为 pNode 添加子节点, 返回值 cNode 指向了新添加的节点}
  cNode.Text := '张三';

  cNode := pNode.AddChild('性别');
  cNode.Text := '男';

  cNode := pNode.AddChild('年龄');
  cNode.Text := '34';
end;

<?xml version="1.0" encoding="GB2312"?>
<科室名单 备注="测试">
     <人员 职务="科长" 备注="正局级">
           <姓名>张三</姓名>
           <性别>男</性别>
           <年龄>34</年龄>
     </人员>
</科室名单>


{-----------------------------------------
添加XML节点
------------------------------------------}
procedure TForm1.Button1Click(Sender: TObject);
var
  newNode, newNodeAdd: IXMLNode;
begin
  newNode := xmldcmnt1.DocumentElement.AddChild('人员');
  newNode.Attributes['职务'] := '秘书';

  newNodeAdd := newNode.AddChild('姓名');
  newNodeAdd.Text := '小翠';

  newNodeAdd := newNode.AddChild('性别');
  newNodeAdd.Text := '女';

  Memo1.Lines := xmldcmnt1.XML; {查看}
  {会在尾部增加:
   <人员 职务="秘书"><姓名>小翠</姓名><性别>女</性别></人员>
  }
end;

<?xml version="1.0" encoding="GB2312"?>
<科室名单 备注="测试">
    <人员 职务="科长" 备注="正局级">
        <姓名>张三</姓名>
        <性别>男</性别>
        <年龄>34</年龄>
    </人员>
    <人员 职务="秘书">
       <姓名>小翠</姓名>
       <性别>女</性别>
    </人员>
</科室名单>


{-----------------------------------------
判断节点的类型
------------------------------------------}
//判断是否是支节点
procedure TForm1.Button1Click(Sender: TObject);
var
  node: IXMLNode;
begin
  node := xmldcmnt1.DocumentElement.ChildNodes[0]; {这是"人员"节点}

  if node.HasChildNodes and not node.IsTextElement then
    ShowMessage('是支节点'); {是支节点}
end;


//判断是否是叶节点
procedure TForm1.Button2Click(Sender: TObject);
var
  node: IXMLNode;
begin
  node := xmldcmnt1.DocumentElement.ChildNodes[0].ChildNodes[0]; {这是"姓名"节点}

  if node.IsTextElement then
    ShowMessage('是叶节点'); {是叶节点}
end;


//判断是否是文本节点
procedure TForm1.Button3Click(Sender: TObject);
var
  node: IXMLNode;
begin
  node := xmldcmnt1.DocumentElement.ChildNodes[0].ChildNodes[0].ChildNodes[0];
  {这是"张三"那个文本节点}

  if node.NodeName='#text' then
    ShowMessage('是文本节点'); {是文本节点}
end;


//判断是否是空节点
procedure TForm1.Button4Click(Sender: TObject);
var
  node: IXMLNode;
begin
  node := xmldcmnt1.DocumentElement.ChildNodes[4];
  {这是根节点下的第五个节点: "辅助人员", xml 中设为空}

  if not node.HasChildNodes then
    ShowMessage('是空节点'); {是空节点}
end;


{-----------------------------------------
NodeValue 和NodeName的区别
------------------------------------------}
procedure TForm1.Button1Click(Sender: TObject);
var
  node: IXMLNode;
begin
  node := xmldcmnt1.DocumentElement;

  node := node.ChildNodes[0]; {现在的 node 指向了第一个人员节点}

  //属性值: NodeValue 是可读写的
  ShowMessage(node.AttributeNodes[0].NodeValue); {科长}
  node.AttributeNodes[0].NodeValue := '正科长';
  ShowMessage(node.AttributeNodes[0].NodeValue); {正科长}

  //属性名: NodeName 是只读的
  ShowMessage(node.AttributeNodes[0].NodeName);  {职务}
  //node.AttributeNodes[0].NodeName := 'xxx';    {如果企图给属性名赋值会出错}

  node := node.ChildNodes[0]; {现在的 node 指向了第一个人员"张三"的姓名节点}

  //节点值: NodeValue 是可读写的
  ShowMessage(node.NodeValue); {张三}
  node.NodeValue := '张老三';
  ShowMessage(node.NodeValue); {张老三}

  //节点名: NodeName 是只读的
  ShowMessage(node.NodeName);  {姓名}
  //node.NodeName := 'xxx';    {如果企图给节点名赋值会出错}
end;

 

{-----------------------------------------
某节点的上一个节点、下一个节点、父节点
------------------------------------------}
procedure TForm1.Button1Click(Sender: TObject);
var
  node,nodeX: IXMLNode;
begin
  node := XMLDocument1.DocumentElement;
  node := node.ChildNodes[1];
  node := node.ChildNodes[1];
  {现在的节点 node 指向了我们的例子中的第二个人员"李四"}

  ShowMessage(node.ChildNodes[0].NodeValue); {女}

  //获取该节点的上一个节点, 它上一个节点应该是李四的姓名
  nodeX := node.PreviousSibling;  {PreviousSibling}
  ShowMessage(nodeX.NodeValue);   {李四}

  //获取该节点的下一个节点, 它下一个节点应该是李四的年龄
  nodeX := node.NextSibling;      {NextSibling}
  ShowMessage(nodeX.NodeValue);   {43}

  //获取该节点的父节点
  nodeX := node.ParentNode;       {ParentNode}
  ShowMessage(nodeX.NodeName);    {人员}
end;


{-----------------------------------------
对象的 XML 属性
------------------------------------------}
//XMLDocument1 对象的 XML 属性
procedure TForm1.Button1Click(Sender: TObject);
begin
  {前面我们经常用这句话, 因为这里的 Lines 与 XML 同属于 TStrings}
  Memo1.Lines := XMLDocument1.XML;

  {如果不怕麻烦, 这样写也可以:}
  Memo1.Lines.Text := XMLDocument1.XML.Text;

  {如果知道了这一点, 那 XML 属性的功能可就多了, 并且这里的 XML 属性是可写的}
  {不过这里要谈的是节点的 XML 属性}
end;


//根节点的 XML 属性
procedure TForm1.Button2Click(Sender: TObject);
var
  node: IXMLNode;
begin
  {先看根节点: XMLDocument1.DocumentElement}
  node := XMLDocument1.DocumentElement;

  //Memo1.Lines := node.XML; {这一句会出错}
  {因为节点的 XML 属性是 WideString 类型的, 应该这样:}
  Memo1.Lines.Text := node.XML; {将会读出根节点与根节点包含的所有内容}

  {还有一个更大的区别: 节点的 XML 是只读的!}
end;


//子节点的 XML 属性
procedure TForm1.Button3Click(Sender: TObject);
var
  node: IXMLNode;
begin
  node := XMLDocument1.DocumentElement;
  node := node.ChildNodes[0];

  Memo1.Lines.Text := node.XML; {会显示一个子节点的全部}
end;


//属性的 XML 属性
procedure TForm1.Button4Click(Sender: TObject);
var
  node: IXMLNode;
begin
  node := XMLDocument1.DocumentElement;
  node := node.AttributeNodes[0]; {属性也是 IXMLNode 类型的}

  ShowMessage(node.NodeName);  {备注}
  ShowMessage(node.NodeValue); {测试}

  {用 XML 属性一次把他们都读出来:}
  ShowMessage(node.XML);       {备注="测试"}
end;


//叶节点的 XML 属性
procedure TForm1.Button5Click(Sender: TObject);
var
  node: IXMLNode;
begin
  node := XMLDocument1.DocumentElement;
  node := node.ChildNodes[0];
  node := node.ChildNodes[0];
  node := node.ChildNodes[0]; {这就是叶节点了}

  ShowMessage(node.XML);  {张三}

  {这时的 XML 属性和 Text 属性一样了}
  ShowMessage(node.Text); {张三}
end;