求教如何读写 *.xml 文件?(200分)

  • 主题发起人 主题发起人 fatBaby
  • 开始时间 开始时间
F

fatBaby

Unregistered / Unconfirmed
GUEST, unregistred user!
网上说用 TXMLDocument,请问是否使用?需要例子。最好是 BCB6 的。
 
The following steps describe how to use TXMLDocument to work directly with an XML document:
1 Add a TXMLDocument component to your form or data module. TXMLDocument appears on the Internet page of the Component palette.
2 Set the DOMVendor property to specify the DOM implementation you want the component to use for parsing and editing an XML document. The Object Inspector lists all the currently registered DOM vendors. For information on DOM implementations, see Using the Document Object Model.
3 Depending on your implementation, you may want to set the ParseOptions property to configure how the underlying DOM implementation parses the XML document.
4 If you are working with an existing XML document, specify the document:
If the XML document is stored in a file, set the FileName property to the name of that file.
You can specify the XML document as a string instead by using the XML property.
5 Set the Active property to True.
Once you have an active TXMLDocument object, you can traverse the hierarchy of its nodes, reading or setting their values. The root node of this hierarchy is available as the DocumentElement
 
宁波吉联计算机技术有限公司研发部 徐荣胜

XML(eXtensible Markup Language可扩展标志语言)在近几年的信息类杂志、网站上可谓是最抢眼的一词。大大小小的信息产品都争相和它搭上关系,唯恐赶不及这辆快车。有着良好口碑的宝蓝
(Borland)系列开发平台也不例外,从6.0版开始就集成了XML组件包,因其使用MSXMLDom解析器,相比于此前广泛应用的XMLParser解析器,MSXMLDom更显规范、中文兼容性更好(元素名、属性名均支持中文),很受开发者青睐。为帮助初学者快速掌握Delphi中的XML编程,笔者特写此文,以供交流。

笔者通过一个读写XML文件的实例来说明XML编程的各个步骤,只需读者有结点、元素、属性的基本概念就能容易的理解本文。笔者所要读入的XML文件结构如下所示,命名为Input.xml。



<学生花名册>

<学生 性别 = "男">

<姓名>李华

<年龄>14

<电话>6287555



<学生 性别 = "男">

<姓名>张三

<年龄>16

<电话>8273425





Input.xml文件的第一行是XML的版本说明,属性encoding宣告使用何种字符集建立,默认以Unicode 编码(UTF-8 或UTF-16),这里用中文GB2312码。第二行“<学生花名册>“是根元素。下面定义了两个学生元素,学生下面嵌套了三个子元素,是对学生的进一步说明。与之相对应的,我们在Delphi中定义如下的学生数据结构,"//"后面的文字是对变量或语句的说明,下同。

TStudent = class {学生}

sex : string; //学生性别

name : string; //学生姓名

age : integer; //学生年龄

phone: string; //电话号码

end;

为了读写,我们需要放置两个TXMLDocument控件,在Delphi VCL面板的Internet标签页里那个标有XML字样的控件就是,当然此控件也可以动态创建,但需要包含必要的文件,这里为简单起见,我们直接放置在窗体上,分别命名为InXMLDoc和OutXMLDoc,InXMLDoc用于调入Input.xml文件,OutXMLDoc用于暂存输出到Output.xml的文档。

在窗体上放个按钮,我们把测试代码直接放置在按钮的单击事件里。先定义几个变量,用来保存临时信息,如下所示:

Root : IXMLNode; //指向XML根结点

Parent_Node: IXMLNode; //指向学生结点

Child_node : IXMLNode; //指向学生的子结点

Student : TStudent; //存单个学生信息

List : TList; //存学生列表

i : integer; //循环变量


我们先来读入XML文件,代码如下:

List := TList.Create; //初始化列表

InXMLDoc.LoadFromFile('Input.xml'); //调入Input.xml文件

Root := InXMLDoc.DocumentElement; //取XML文件的根结点,即“<学生花名册>”

Parent_Node := Root.ChildNodes.First; //使Parent_Node指向学生结点

while (Parent_Node <> nil) do //循环取多个学生,可再多加几个学生信息测试

begin

if (Parent_Node.NodeName = '学生') then //判断是否为学生结点

begin

Student := TStudent.Create; //新建一个学生的结构信息

Student.sex := Parent_Node.Attributes['性别']; //取学生的性别属性

Child_Node := Parent_Node.ChildNodes.First;

//使Child_Node指向该学生的第一个子结点信息

while (Child_Node <> nil) do //循环取学生的各个子各点

begin

if (Child_Node.NodeName = '姓名') then //判断是否为姓名结点

Student.name := Child_Node.Text //取姓名结点的值,取于name字段中

else if (Child_Node.NodeName = '年龄') then //此行起后四行与前两行类似

Student.age := StrToInt(Child_Node.Text)

else if (Child_Node.NodeName = '电话') then

Student.phone := Child_Node.Text;

Child_Node := Child_Node.NextSibling; //顺序取下一个学生的子结点信息

end;

List.Add(Student); //把一个学生信息加入列表

end;

Parent_Node := Parent_Node.NextSibling; //顺序取下一个学生信息

end;

到这儿,所有的学生信息都已存到List列表里面了,读者可以跟踪代码测试。


下面我们把List里的临时学生信息存到Output.xml文件里,代码如下:

OutXMLDoc.Active := true; //激活OutXMLDoc,自动初始化空的XML文档

OutXMLDoc.Encoding := 'GB2312'; //设置字符集

Root := OutXMLDoc.AddChild('学生花名册'); //建根结点

for i := 0 to List.Count - 1 do //循环取各个学生信息

begin

Student := List.Items; //顺序取一个学生信息

if (Student <> nil) then

begin

Parent_Node := Root.AddChild('学生'); //根结点后添加一个学生结点

Parent_Node.Attributes['性别'] := Student.sex; //给学生结点设置性别属性

Child_Node := Parent_Node.AddChild('姓名'); //学生结点后添加一个姓名结点

Child_Node.Text := Student.name; //设置姓名的文本值

Child_Node := Parent_Node.AddChild('年龄'); //此行起后四行与前两行类似

Child_Node.Text := IntToStr(Student.age);

Child_Node := Parent_Node.AddChild('电话');

Child_Node.Text := Student.phone;

end;

end;

OutXMLDoc.SaveToFile('Output.xml'); //把组织好的XML文档存于Output.xml文件中

OutXMLDoc.Active := false; //钝化(关闭)OutXMLDoc

List.Free; //最后释放保存临时学生信息的列表


好了,看看Input.xml和Output.xml内容是不是一样。是不是很简单呢?其实在C++ Builder也有相同的组件,只需将Pascal语法转换成C++语法
 
class TJJXMLDocument
{
public:
__fastcall TJJXMLDocument(TXMLDocument* XMLDoc,
String Software,
String Method,
int DocumentVersion);
__fastcall ~TJJXMLDocument();
protected:
bool m_Connected;
TXMLDocument* m_XMLDoc;
String m_Software; // 软件名称
String m_Method; // 最高祖先节点
int m_DocumentVersion;
private:

virtual bool __fastcall Encode()=0;
virtual bool __fastcall Decode()=0;
public:
bool __fastcall SaveToFile(TFileName FileName); // 保存
bool __fastcall LoadFromFile(TFileName FileName); // 读取
};
//---------------------------------------------------------------------------
__fastcall TJJXMLDocument::TJJXMLDocument(TXMLDocument* XMLDoc,
String Software,
String Method,
int DocumentVersion)
: m_XMLDoc(XMLDoc),
m_Software(Software),
m_Method(Method),
m_DocumentVersion(DocumentVersion)
{
}
//---------------------------------------------------------------------------
__fastcall TJJXMLDocument::~TJJXMLDocument()
{
m_XMLDoc = NULL;
}
//---------------------------------------------------------------------------
bool __fastcall TJJXMLDocument::SaveToFile(TFileName FileName) // 保存
{
bool Result = false;
try {
if ( Encode() )
{
m_XMLDoc->SaveToFile(FileName);

Result = true;
}
}catch(...){
}

return Result;
}
//---------------------------------------------------------------------------
bool __fastcall TJJXMLDocument::LoadFromFile(TFileName FileName) // 读取
{
bool Result = false;
try {
m_XMLDoc->LoadFromFile(FileName);

Result = Decode();
}catch(...){
}

return Result;
}
// ========================================================================================================
// ========================================================================================================
// ========================================================================================================
// ========================================================================================================
class TXMLOnlineUpdate : public TJJXMLDocument
{
public:
__fastcall TXMLOnlineUpdate(TXMLDocument* XMLDoc, String Software);
__fastcall ~TXMLOnlineUpdate();

public: // 信息清单
void __fastcall Init(); // 被成员变量进行初始化,同时在读信息失败时的原始化恢复
// === (淘汰的发布版本) ==============================================================================
// WashOut
int wso_WashOutVersion; // 已被淘汰的版本号 - WashOutVersion

// === (正式的发布版本) ==============================================================================
// Release
String rls_VersionString; // 完整版本号字符串 - VersionString

int rls_ExecuteFileVersion; // 可执行文件版本号 - ExecuteFileVersion
int rls_DatabaseFileVersion; // 数据库文件版本号 - DatabaseFileVersion

String rls_ExecuteFileURL; // 文件下载 URL - ExecuteFileURL
String rls_EXEFileName; // 可执行文件名
String rls_DatabaseFileURL; // 文件下载 URL - DatabaseFileURL
String rls_DBFFileName; // 数据库文件名

String rls_PackageDownloadURL; // 完整软件包下载 URL - PackageDownloadURL

// === (最新的测试版本) ==============================================================================
// Debug
String dbg_VersionString; // 完整版本号字符串 - VersionString

int dbg_ExecuteFileVersion; // 可执行文件版本号 - ExecuteFileVersion
int dbg_DatabaseFileVersion; // 数据库文件版本号 - DatabaseFileVersion

String dbg_ExecuteFileURL; // 文件下载 URL - ExecuteFileURL
String dbg_EXEFileName; // 可执行文件名
String dbg_DatabaseFileURL; // 文件下载 URL - DatabaseFileURL
String dbg_DBFFileName; // 数据库文件名

String dbg_PackageDownloadURL; // 完整软件包下载 URL - PackageDownloadURL

private:
virtual bool __fastcall Decode(); // 从 XML 中解码
virtual bool __fastcall Encode(); // 编码写入 XML

public:
bool __fastcall JudgeEXEVersion(int CurrentEXEVersion); // 确定是否需要升级
bool __fastcall JudgeDBFVersion(int CurrentDBFVersion); // 确定是否需要升级

bool __fastcall JudgeAlphaStageProducts_EXE(int CurrentEXEVersion); // 确定是否存在更新的测试版
bool __fastcall JudgeAlphaStageProducts_DBF(int CurrentDBFVersion); // 确定是否存在更新的测试版
};
__fastcall TXMLOnlineUpdate::TXMLOnlineUpdate(TXMLDocument* XMLDoc, String Software)
: TJJXMLDocument(XMLDoc, Software, "OnlineUpdate", 1)
{
Init();
}
//---------------------------------------------------------------------------
__fastcall TXMLOnlineUpdate::~TXMLOnlineUpdate()
{
}
//---------------------------------------------------------------------------
void __fastcall TXMLOnlineUpdate::Init() // 被成员变量进行初始化,同时在读信息失败时的原始化恢复
{
// === (淘汰的发布版本) ==============================================================================
// WashOut
wso_WashOutVersion = 0; // 已被淘汰的版本号 - WashOutVersion

// === (正式的发布版本) ==============================================================================
// Release
rls_VersionString = "0.0.0.0"; // 完整版本号字符串 - VersionString

rls_ExecuteFileVersion = 0; // 可执行文件版本号 - ExecuteFileVersion
rls_DatabaseFileVersion = 0; // 数据库文件版本号 - DatabaseFileVersion

rls_ExecuteFileURL = ""; // 文件下载 URL - ExecuteFileURL
rls_EXEFileName = "";
rls_DatabaseFileURL = ""; // 文件下载 URL - DatabaseFileURL
rls_DBFFileName = "";

rls_PackageDownloadURL = ""; // 完整软件包下载 URL - PackageDownloadURL

// === (最新的测试版本) ==============================================================================
// Debug
dbg_VersionString = "0.0.0.0"; // 完整版本号字符串 - VersionString

dbg_ExecuteFileVersion = 0; // 可执行文件版本号 - ExecuteFileVersion
dbg_DatabaseFileVersion = 0; // 数据库文件版本号 - DatabaseFileVersion

dbg_ExecuteFileURL = ""; // 文件下载 URL - ExecuteFileURL
dbg_EXEFileName = "";
dbg_DatabaseFileURL = ""; // 文件下载 URL - DatabaseFileURL
dbg_DBFFileName = "";

dbg_PackageDownloadURL = ""; // 完整软件包下载 URL - PackageDownloadURL
}
//---------------------------------------------------------------------------
bool __fastcall TXMLOnlineUpdate::Decode()
{
if ( ! m_XMLDoc->Active )
{
try {
m_XMLDoc->Active = true;
}catch(...){
return false;
}
}

Init();

_di_IXMLNode NodeSoftware;
_di_IXMLNode NodeWashOut;
_di_IXMLNode NodeVersion;
_di_IXMLNode NodeDebug;
_di_IXMLNode Node;

NodeSoftware = m_XMLDoc->ChildNodes->FindNode(m_Software);

if ( NodeSoftware )
{
String s;

s = NodeSoftware->GetAttribute("Method");
if ( s == "OnlineUpdate" )
{
m_Method = s;

s = NodeWashOut->GetAttribute("Version");
if ( m_DocumentVersion >= s.ToIntDef(0) );
{
m_DocumentVersion = s.ToIntDef(0);

NodeWashOut = NodeSoftware->ChildNodes->FindNode("WashOut");
if ( NodeWashOut )
{
s = NodeWashOut->GetAttribute("Version");
wso_WashOutVersion = s.ToIntDef(0);
}

NodeVersion = NodeSoftware->ChildNodes->FindNode("Release");
if ( NodeVersion )
{
rls_VersionString = NodeVersion->GetAttribute("Version");

Node = NodeVersion->ChildNodes->FindNode("ExecuteFile");
if ( Node )
{
rls_ExecuteFileVersion = Node->GetAttribute("Version" );
rls_ExecuteFileURL = Node->GetAttribute("URL" );
rls_EXEFileName = Node->GetAttribute("FileName");
}

Node = NodeVersion->ChildNodes->FindNode("DatabaseFile");
if ( Node )
{
rls_DatabaseFileVersion = Node->GetAttribute("Version" );
rls_DatabaseFileURL = Node->GetAttribute("URL" );
rls_DBFFileName = Node->GetAttribute("FileName");
}
}

NodeVersion = NodeSoftware->ChildNodes->FindNode("Debug");
if ( NodeVersion )
{
dbg_VersionString = NodeVersion->GetAttribute("Version");

Node = NodeVersion->ChildNodes->FindNode("ExecuteFile");
if ( Node )
{
dbg_ExecuteFileVersion = Node->GetAttribute("Version" );
dbg_ExecuteFileURL = Node->GetAttribute("URL" );
dbg_EXEFileName = Node->GetAttribute("FileName");
}

Node = NodeVersion->ChildNodes->FindNode("DatabaseFile");
if ( Node )
{
dbg_DatabaseFileVersion = Node->GetAttribute("Version" );
dbg_DatabaseFileURL = Node->GetAttribute("URL" );
dbg_DBFFileName = Node->GetAttribute("FileName");
}
}
}
}

m_XMLDoc->Active = false;

return true;
}
//---------------------------------------------------------------------------
bool __fastcall TXMLOnlineUpdate::Encode()
{
m_XMLDoc->LoadFromXML(WideString(""));
m_XMLDoc->Active = true;
m_XMLDoc->ChildNodes->Clear();
m_XMLDoc->StandAlone = "yes";

_di_IXMLNode NodeSoftware;
_di_IXMLNode NodeWashOut;
_di_IXMLNode NodeRelease;
_di_IXMLNode NodeDebug;
_di_IXMLNode Node;

// ===================================================================================================
// NodeAncestor = m_XMLDoc->CreateNode(m_Ancestor, ntElement, "FriendSafe");
NodeSoftware = m_XMLDoc->CreateNode(m_Software);
NodeSoftware->SetAttribute("Method", m_Method);
NodeSoftware->SetAttribute("Version", m_DocumentVersion);
m_XMLDoc->ChildNodes->Add(NodeSoftware);

// ===================================================================================================
NodeWashOut = NodeSoftware->AddChild("WashOut");
NodeWashOut->SetAttribute("Version", wso_WashOutVersion);

// ===================================================================================================
NodeRelease = NodeSoftware->AddChild("Release");
NodeRelease->SetAttribute("Version", rls_VersionString);
// NodeRelease->SetText(rls_ExecuteFileURL);
Node = NodeRelease->AddChild("ExecuteFile");
Node->SetAttribute("Version", rls_ExecuteFileVersion);
Node->SetAttribute("URL", rls_ExecuteFileURL);
Node->SetAttribute("FileName", rls_EXEFileName);
Node = NodeRelease->AddChild("DatabaseFile");
Node->SetAttribute("Version", rls_DatabaseFileVersion);
Node->SetAttribute("URL", rls_DatabaseFileURL);
Node->SetAttribute("FileName", rls_DBFFileName);

// ===================================================================================================
NodeDebug = NodeSoftware->AddChild("Debug");
NodeDebug ->SetAttribute("Version", dbg_VersionString);
// NodeDebug ->SetText(dbg_DatabaseFileURL);
Node = NodeDebug->AddChild("ExecuteFile");
Node->SetAttribute("Version", dbg_ExecuteFileVersion);
Node->SetAttribute("URL", dbg_ExecuteFileURL);
Node->SetAttribute("FileName", dbg_EXEFileName);
Node = NodeDebug->AddChild("DatabaseFile");
Node->SetAttribute("Version", dbg_DatabaseFileVersion);
Node->SetAttribute("URL", dbg_DatabaseFileURL);
Node->SetAttribute("FileName", dbg_DBFFileName);

return true;
}
//---------------------------------------------------------------------------
bool __fastcall TXMLOnlineUpdate::JudgeEXEVersion(int CurrentEXEVersion) // 确定是否需要升级
{
return false;
}
//---------------------------------------------------------------------------
bool __fastcall TXMLOnlineUpdate::JudgeDBFVersion(int CurrentDBFVersion) // 确定是否需要升级
{
return false;
}
 
这样试试,也许更简单.
File->New->Other...->New->XML Data Binding
 
后退
顶部