解析XML问题 高手请帮忙(在线等待) ( 积分: 100 )

  • 主题发起人 猪头哥哥
  • 开始时间

猪头哥哥

Unregistered / Unconfirmed
GUEST, unregistred user!
XML原文
<?xml version="1.0" encoding="gb2312" ?>
- <CRS.CommandSet.PNR>
<Success />
<Errors />
<PNR>TBGYF</PNR>
<AgentOffice />
- <Passengers>
<Passenger ElementNo="1" PsgID="1" Name="CHEN/SHUNHAO" Type="0" CardType="" CardNo="" BirthDay="" CarrierPsgID="" Country="" />
<Passenger ElementNo="2" PsgID="2" Name="LAN/XIAOFANG" Type="0" CardType="" CardNo="" BirthDay="" CarrierPsgID="" Country="" />
<Passenger ElementNo="3" PsgID="3" Name="TADASHI/NISHIKAWA" Type="0" CardType="" CardNo="" BirthDay="" CarrierPsgID="" Country="" />
<Passenger ElementNo="4" PsgID="4" Name="WU/SIPING" Type="0" CardType="" CardNo="" BirthDay="" CarrierPsgID="" Country="" />
</Passengers>
- <Flights>
<Flight ElementNo="5" ID="1" Type="0" Carrier="CZ" Flight="389" BoardPoint="CAN" OffPoint="KIX" Week="TH" DepartureDate="2007-04-05" DepartureTime="09:20" ArriveDate="2007-04-05" ArriveTime="13:50" Class="H" ActionCode="RR" Seats="4" Meal="" Stops="" Avail="" Night="" ETKT="" Changed="" LinkLevel="" Allow="" />
<Flight ElementNo="6" ID="2" Type="0" Carrier="CZ" Flight="390" BoardPoint="KIX" OffPoint="CAN" Week="SU" DepartureDate="2007-04-08" DepartureTime="14:50" ArriveDate="2007-04-08" ArriveTime="17:20" Class="H" ActionCode="RR" Seats="4" Meal="" Stops="" Avail="" Night="" ETKT="" Changed="" LinkLevel="" Allow="" />
</Flights>
+ <Contacts>
<Contacts No="CAN/T CAN/020-87013606/GUANGDONG NEW GENERATION BUSINESS MANAGEMENT CO.,LTD /WANGLIMING ABCDEFG" />
<Contacts No="34712064" />
</Contacts>
<PNRs />
<TicketNos />
<RMKs />
<SSRs />
<OSIs />
- <Segments>
<Segment ElementNo="10" Text="SSR OTHS 1E *PLS ADVISE PAX TO RCFM CZ FLT NO LATER THAN 72HRS BF" />
<Segment ElementNo="11" Text="SSR PSPT" />
<Segment ElementNo="12" Text="SSR PSPT" />
<Segment ElementNo="13" Text="SSR PSPT" />
<Segment ElementNo="14" Text="SSR PSPT" />
</Segments>
</CRS.CommandSet.PNR>
----------------------------------------------------------------
解析方法:
function getnodefromIXMLNodeList(childnodes: IXMLNodeList; nodename: string): IXMLNode;
var
i: Integer;
begin
for i := 1 to childnodes.Count do begin
if (childnodes.Get(i - 1).NodeName = nodename) then begin
result := childnodes[i - 1];
exit;
end;
end;
end;
{-------------------------------------------------------------------------------
Fun/Pro: GetXMLNodeSpecialValue
@Date: 2004.12.11
@Param: xmlFile xml文件
@Param: xmlnodepath 节点
@Param: xmlattrname 节点中的属性名称,如果直接取节点值则可以忽略此参数。
@Param: XMLSpecialName 要查找的节点中属性名
@Param: XMLSpecialValue 要查找的节点中某属性对应的值
@Param: dep 节点的参数的分隔符,默认为.
@Return: 某属性的值
-------------------------------------------------------------------------------}
function GetXMLNodeSpecialValue(strEntityEngineFile:String; XMLNodePath:String;
const XMLAttrName:String='; const XMLSpecialName:String='; const XMLSpecialValue:String='; const dep:Char ='.'):String;
var
xmlDocument :IXMLDocument;
node :IXMLNode;
xmlnodeList :TStrings;
i :Integer;
urlcount :Integer;
begin
//xml节点路径
xmlnodeList:=TStringList.Create;
xmlnodeList.Delimiter:=dep;
xmlnodeList.DelimitedText:=xmlnodepath;
urlcount:=xmlnodeList.Count;
//xml对象
xmlDocument :=TXMLDocument.Create(nil);
xmlDocument.LoadFromFile(strEntityEngineFile);
xmlDocument.Active:=true;
try
node:= xmlDocument.DocumentElement;
if(node.NodeName = xmlnodeList[0]) then begin
//扫描节点
for i := 1 to urlcount-1 do begin
if(node<>nil) then
begin
node := getnodefromIXMLNodeList(node.ChildNodes,xmlnodeList);
end
else Break;
end;
if(node=nil)then begin
result:=';
end else begin
//判断是取属性还是取节点内容
if(Trim(xmlattrname)=') then
result:=node.Text
else
begin
result := node.AttributeNodes.Nodes[XMLSpecialName].NodeValue; //这里不想再声明一个临时变量了,就用result来比较,可能有隐患。
while ((result <> XMLSpecialValue)) do
begin
node := node.NextSibling;
while (node.NodeName = '#comment') do
begin
node:= node.NextSibling;
end;
result := node.AttributeNodes.Nodes[XMLSpecialName].NodeValue;
end;
result:=node.AttributeNodes.Nodes[XMLAttrName].NodeValue;
end;
end;
end else begin
result:=';
end;

except
result:='error';
end;
xmlDocument.Active:=false;
end;
问题:
1:AttributeNodes 是什么作用?每次到这里都运行不下去.看了Delphi帮助E文看的不是很明白.
2:难点在于下面这段,不懂如何循环解析.
<Passenger ElementNo="1" PsgID="1" Name="CHEN/SHUNHAO" Type="0" CardType="" CardNo="" BirthDay="" CarrierPsgID="" Country="" />
<Passenger ElementNo="2" PsgID="2" Name="LAN/XIAOFANG" Type="0" CardType="" CardNo="" BirthDay="" CarrierPsgID="" Country="" />
<Passenger ElementNo="3" PsgID="3" Name="TADASHI/NISHIKAWA" Type="0" CardType="" CardNo="" BirthDay="" CarrierPsgID="" Country="" />
<Passenger ElementNo="4" PsgID="4" Name="WU/SIPING" Type="0" CardType="" CardNo="" BirthDay="" CarrierPsgID="" Country="" />
3:期待各位高手能给出调用例子.谢谢.
 
自己顶一下....................
 
很简单,也就是个树,搞来搞去也就那几个函数,去看看:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3691012;
我自己以前写的代码,参考下
<?xml version="1.0" encoding="GB2312"?>
<GradeMeans>
<GradeSection id="1" name="综合评分法" IsBidHide="false">
<GradeItem name="AQSGLower" value="2957" type="0"/>
<GradeItem name="AQSGHigh" value="2958" type="0"/>
<Technology>
<TechnologyItem Idx="1" Name="测试1" Score="0.1" />
<TechnologyItem Idx="2" Name="测试2" Score="0.2" />
<TechnologyItem Idx="3" Name="测试3" Score="0.3" />
</Technology>
</GradeSection>
</GradeMeans>


unit MainFrm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,XmlToMdb, DB, ADODB;

type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
procedure Ini();
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Ini;
begin
Self.Caption:= '主窗口';
Button1.Caption:= '开始导数据';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Ini;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
aMeanItems: WideString;
begin
aMeanItems:= GetMeanItemsFromXmlFile(ExtractFilePath(Application.ExeName)+'XmlToMdb.xml');
BudgetToGradeMDB(ExtractFilePath(Application.ExeName)+'招标文件.mdb','lisong',aMeanItems);
Application.MessageBox('导出数据完成!','提示框',MB_OK);
end;

end.

{-----------------------------------------------------------------------------
Unit Name: XmlToMdb
Author: lisong
Purpose: 实现从xml导出数据到mdb数据库
History:
Date: 2007-1-12
-----------------------------------------------------------------------------}

unit XmlToMdb;

interface
uses XMLDoc,XMLIntf,ADODB;

procedure IniDataBaseConnetion(MDBPath: WideString;aADOQuery: TADOQuery);
//******************************************************************************
//向需要的表中插入数据
//******************************************************************************
procedure td_AuditMethodsInserted(aADOQuery: TADOQuery;ProjectID: WideString;aXMLNode: IXMLNode);
procedure td_AuditParaInserted(aADOQuery: TADOQuery;ProjectID: WideString;aXMLNode: IXMLNode);
procedure td_TechnologyInserted(aADOQuery: TADOQuery;ProjectID: WideString;tech_JSMethodID: integer; aXMLNode: IXMLNode);
procedure DoADOQuery(aADOQuery: TADOQuery;sSql: string);//对数据集进行相应的操作
procedure ClearDataForIni(aADOQuery: TADOQuery); //初始化数据库中的数据:清空

//得到一个xml文件的文本格式的字符串
function GetMeanItemsFromXmlFile(XMLfileName: String): WideString;
//通过节点名称递归查找节点
function FindNodeByNodeName(aXMLNode: IXMLNode;NodeName: string): IXMLNode;
//核心函数:从xml导出数据到mdb数据库
procedure BudgetToGradeMDB(MDBPath, ProjectID, MeanItems: WideString);

implementation

uses SysUtils, Classes, DB;
const
//ADO控件的连接字符串
ConntionString_head = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=';
ConntionString_end = ';Persist Security Info=False';

{ TXmlToMdb }

procedure IniDataBaseConnetion(MDBPath: WideString;aADOQuery: TADOQuery);
begin
try
aADOQuery.ConnectionString:= ConntionString_head + MDBPath + ConntionString_end;
except
raise Exception.Create('数据库联结失败!');
end;
end;

function GetMeanItemsFromXmlFile(XMLfileName: String): WideString;
var
aXMLDoc: IXMLDocument;//接口生存期自管理
begin
aXMLDoc:=TXMLDocument.Create(nil);
try
aXMLDoc.LoadFromFile(XMLfileName);
Result:= aXMLDoc.XML.Text;
except
raise Exception.Create('文件载入失败!');
end;
end;

procedure DoADOQuery(aADOQuery: TADOQuery;sSql: string);
begin
with aADOQuery do
begin
DisableControls;
if Active then
Active := false;
SQL.Text := sSql;
try
ExecSQL;
Except
raise Exception.Create('do: '+ sSql +':Error');
end;
EnableControls;
end;
end;

procedure ClearDataForIni(aADOQuery: TADOQuery);
function td_AuditMethodsClearSql(): String;
begin
Result:= 'delete from td_AuditMethods';
end;
function td_AuditParaClearSql(): string;
begin
Result:= 'delete from td_AuditPara';
end;
function td_TechnologyClearSql(): string;
begin
Result:= 'delete from td_Technology';
end;
begin
DoADOQuery(aADOQuery,td_AuditMethodsClearSql);
DoADOQuery(aADOQuery,td_AuditParaClearSql);
DoADOQuery(aADOQuery,td_TechnologyClearSql);
end;

procedure td_AuditMethodsInserted(aADOQuery: TADOQuery;ProjectID: WideString;aXMLNode: IXMLNode);
var
sSql: String;
begin
if aXMLNode <> nil then
begin
sSql:= 'insert into td_AuditMethods(aume_ProjectID,aume_ScoreMethods,aume_IsBidHide)'
+' values(%s,%d,%s)';
sSql:= Format(sSql,[QuotedStr(ProjectID),StrToInt(aXMLNode.Attributes['id']),
aXMLNode.Attributes['IsBidHide']]);
end;
DoADOQuery(aADOQuery,sSql);
end;

procedure td_AuditParaInserted(aADOQuery: TADOQuery;ProjectID: WideString;
aXMLNode: IXMLNode);
var
sSql: String;
begin
if aXMLNode <> nil then
begin
sSql:= 'insert into td_AuditPara (aupa_ProjectID,aupa_ParaType,aupa_ParaName,aupa_ParaValue)'
+'values(%s,%d,%s,%s)';
sSql:= Format(sSql,[QuotedStr(ProjectID),StrToInt(aXMLNode.Attributes['type']),
QuotedStr(aXMLNode.Attributes['name']),QuotedStr(aXMLNode.Attributes['value'])]);
end;
DoADOQuery(aADOQuery,sSql);
end;

procedure td_TechnologyInserted(aADOQuery: TADOQuery;ProjectID: WideString;
tech_JSMethodID: integer;aXMLNode: IXMLNode);
var
sSql: String;
begin
if aXMLNode <> nil then
begin
sSql:= 'insert into td_Technology (tech_ProjectID,tech_JSMethodID,tech_Idx,tech_Name,tech_Score)'
+'values(%s,%s,%d,%s,%f)';
sSql:= Format(sSql,[QuotedStr(ProjectID),QuotedStr(IntToStr(tech_JSMethodID)),
StrToInt(aXMLNode.Attributes['Idx']),QuotedStr(aXMLNode.Attributes['Name']),
StrToFloat(aXMLNode.Attributes['Score'])]);
end;
DoADOQuery(aADOQuery,sSql);
end;

function FindNodeByNodeName(aXMLNode: IXMLNode;NodeName: string): IXMLNode;
var
i: integer;
begin
Result:= nil;
if aXMLNode <> nil then
begin
for i:= 0 to aXMLNode.ChildNodes.Count-1 do
begin
if aXMLNode.ChildNodes.NodeName = NodeName then
begin
Result:= aXMLNode.ChildNodes;
Break;
end
else
Result:=FindNodeByNodeName(aXMLNode.ChildNodes,NodeName);
end;
end;
end;

//******************************************************************************
//核心函数:从xml导出数据到mdb数据库
//MDBPath:文件路径,ProjectID:项目ID,MeanItems:方法的xml
//******************************************************************************
procedure BudgetToGradeMDB(MDBPath, ProjectID,
MeanItems: WideString);
var
aADOQuery: TADOQuery;
aXMLDoc: IXMLDocument; //接口生存期自管理
aXMLNode,aTempXMLNode: IXMLNode;
i,j: integer;
TempTech_JSMethodID: integer;
begin
TempTech_JSMethodID:= 0;//自己设置的数据库tech_JSMethodID字段值变量
aADOQuery:= TADOQuery.Create(nil);
aXMLDoc:= TXMLDocument.Create(nil);

try
IniDataBaseConnetion(MDBPath,aADOQuery);//初始化数据库联结
ClearDataForIni(aADOQuery);//清空以前数据,现在从新生成
aXMLDoc.XML.Text:= MeanItems;
aXMLDoc.Active:= true;//一定要设置为true,切记
aXMLNode:= aXMLDoc.ChildNodes.FindNode('GradeMeans');
if aXMLNode <> nil then
begin
//处理表td_AuditMethods
for i:= 0 to aXMLNode.ChildNodes.Count-1 do
aTempXMLNode:= FindNodeByNodeName(aXMLNode,'GradeSection');
if aTempXMLNode <> nil then
for j:= 0 to aTempXMLNode.ParentNode.ChildNodes.Count-1 do
begin
if aTempXMLNode.ParentNode.ChildNodes[j].NodeName = 'GradeSection' then
td_AuditMethodsInserted(aADOQuery,ProjectID,aTempXMLNode.ParentNode.ChildNodes[j]);
end;

//处理表td_AuditParaInserted
for i:= 0 to aXMLNode.ChildNodes.Count-1 do
aTempXMLNode:= FindNodeByNodeName(aXMLNode,'GradeItem');
if aTempXMLNode <> nil then
for j:=0 to aTempXMLNode.ParentNode.ChildNodes.Count-1 do
begin
if aTempXMLNode.ParentNode.ChildNodes[j].NodeName = 'GradeItem' then
td_AuditParaInserted(aADOQuery,ProjectID,aTempXMLNode.ParentNode.ChildNodes[j]);
end;

//处理表td_Technology
for i:= 0 to aXMLNode.ChildNodes.Count-1 do
aTempXMLNode:= FindNodeByNodeName(aXMLNode,'TechnologyItem');
if aTempXMLNode <> nil then
for j:=0 to aTempXMLNode.ParentNode.ChildNodes.Count-1 do
if aTempXMLNode.ParentNode.ChildNodes[j].NodeName = 'TechnologyItem' then
begin
Inc(TempTech_JSMethodID);
td_TechnologyInserted(aADOQuery,ProjectID,TempTech_JSMethodID,aTempXMLNode.ParentNode.ChildNodes[j]);
end;
end;
finally
aADOQuery.Free;
end;
end;

end.
 
接受答案了.
 

Similar threads

I
回复
0
查看
609
import
I
I
回复
0
查看
737
import
I
I
回复
0
查看
681
import
I
I
回复
0
查看
2K
import
I
I
回复
0
查看
2K
import
I
顶部