热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

IXMLDocument的Node属性和DocumentElement属性区别

今天写一个Xml配置的读写类,遇到了几个问题,记录如下。1)读一个并不存在的节点竟然不出问题?用了一个很简单的xml文件,如下<!--test.xml-

今天写一个Xml配置的读写类,遇到了几个问题,记录如下。

1)读一个并不存在的节点竟然不出问题?

用了一个很简单的 xml 文件,如下 


xml version="1.0" encoding="GB2312"?>
<value>
   
<v> abc def ghi v>
value>

读写代码如下:

// 竟然没有delphi的代码模版?kao

procedure TForm1.btnReadClick(Sender: TObject);
var
  N: IXMLNode;
  St: TStringList;
  I: Integer;    
begin
  St :
=  TStringList.Create;
  
try

    St.Text :
=  edtNodeName.Text;
    St.Text :
= StringReplace(St.Text, '/', #13#10, [rfReplaceAll]);  // 输入的Node序列格式为"ParentNode/SubNode",

    N :=  xmldoc1.DocumentElement;
    
for I := 0 to St.Count - 1 do

    begin
      N :
=  N.ChildNodes.Nodes[St[I]];
      
if N =
 nil then
        MessageDlg(Format(
'无此节点 "%s"', [St[I]]), mtError, [mbOK] , 0
);
    end;
    
if N <>
 nil then
      
if
 not N.IsTextElement then
      begin
        MessageDlg(
'not text node', mtInformation, [mbOK], 0
);
        edtResult.Text :
= Format('%s is %s'
, [N.NodeName, NodeTypeToStr(N.NodeType)]);
      end
      
else

        edtResult.Text :
=  N.Text;
  
finally

    St.Free;
  end;
end;

该代码从名为 btnNodeName  的编辑框中读取Node的名字,支持多层级,如要读取上面的test.xml文件的v节点的值,只要输入 “value/v” (写这段代码时是这样想的,但是这样想是错误的,后面有说明).

但是,测试的时候,发现总是报 v 不是 TextElement,百思不得其解,后来无意中发现原来执行时打开的是另外一个xml文件,但是该xml文件的结构完全不一样,压根就没有 value 和 v 节点,怎么还能够读取到这两个节点呢?

仔细看了一下帮助,在对 IXMLNodeList.Nodes属性的解释中,发现了这段说明:

If IndexOrName does not identify a node in the list, and if the document that contains this node list's parent includes doNodeAutoCreate in its Options property, then the node list tries to create a new node with the name specified by IndexOrName. If the node list can't create the new node, it raises an exception.

原来,如果 Nodes 属性的参数 IndexOrName(为结点名时) 所指定的节点不存在,并且 其所属的 IXmlDocument 的 Options 属性包含了doNodeAutoCreate值,则会自动创建一个新的节点,命名为 IndexOrName 的值,所以才会出现读取不存在的节点也不会出错的现象,而且因为该节点加入后,没有设置值,所以类型是ntElement,而不是ntText,所以会报不是 TextElement。我们只要在创建IXmlDocument对象后加入下面的代码就可避免这种情况:

xmlDoc :=  TXmlDocument.Create(nil);
xmlDoc.Options :
= xmlDoc.Options - [doNodeAutoCreate];

2)value 节点不存在?

修正了上面的问题之后测试,edtNodeName 输入为“value/v”,报错,提示“value”节点不存在,奇怪,怎么会不存在,这回打开的确实是test.xml文件啊。查看代码,发现 TXMLDocument 读取 DocmentElement 属性是这样实现的:

function TXMLDocument.GetDocumentElement: IXMLNode;
begin
  CheckActive;
  Result :
=
 nil;
  
if
 Node.HasChildNodes then
  begin
    Result :
=
 Node.ChildNodes.Last;
    
while Assigned(Result) and (Result.NodeType <> ntElement) do

      Result :
=  Result.PreviousSibling;
  end;
end;

这个 Node 是个什么东西?继续查看有关 Node 的代码,并且翻看帮助,帮助是这样说的:

Read Node to access the document node for the XML document. The document node represents information about the entire document. It may have several child nodes, which represent comments, processing instructions, and which include the DocumentElement node that acts as the root of the data hierarchy.

原来 Node 才是 xml 文档的真正根节点,而 DocumentElement 只是我们的xml文件的内容的根节点,是 Node 的子节点,对于上面的 test.xml 来说, DocmentElement 就是表示 value 节点,而在上面的代码中,我们实际上读取的是“value/value”节点,难怪会不存在,把上面的

N := xmldoc1.DocumentElement;

改为

N := xmldoc1.Node;

就 OK 了。


推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 怀疑是每次都在新建文件,具体代码如下 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
author-avatar
batman@zhou
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有