Wel*_*onD 0 xml delphi dataset
我正在尝试使用XML将文件加载到Delphi数据集中 mydataset.loadfromfile("myfile.xml")
问题是我不知道XML字段名称和它有多少字段.我知道XML只有一个级别,例如:
<DOCTO id ="3892" usuario="2" data="22/12/2015 10:33:22">
<CONDUTA_1>teste conduta 1</CONDUTA_1>
<CONDUTA_2>teste conduta 2</CONDUTA_2>
</DOCTO>
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种方法来加载xml而不创建之前的字段.
正如你所说,你不能使用XMLMapper,我已经将我的答案部分移到了底部.
由于您无法使用XmlMapper,因此您需要使用XML解析器自行解析XML.下面的示例使用Windows附带的XML DOM Parser,您需要MSXML在Uses列表中找到它.为了说明如何执行此操作,我将使用与您的结构相同但具有抽象节点和属性名称的XML,以避免XML的节点名称和值分散注意力.
<data a1="a" a2="b" a3="c">
<r1>11111</r1>
<r2>22222</r2>
</data>
Run Code Online (Sandbox Code Playgroud)
在一个极端,字段名称可能是<data>节点属性的名称a1,a2,a3,字段值可能是这些属性的值.
如何获得这些在LoadFromAttributes例程中显示.基本上,它将XML加载到XMLDoc对象中,使用XPath查询来查找<data>节点,并且它们获取其属性以创建数据集字段并设置其值.
在另一个极端,子节点<r1>和<r2>可能的字段名和它们的节点文本字段值.该LoadFromNodes程序显示了如何做到这一点.
当然,在实践中,XML的语义可能意味着字段名称和值是两者的混合,但是由于您没有说明XML的"含义",我将不得不将其留给您.
TForm1 = class(TForm)
Memo1: TMemo;
CDS1: TClientDataSet;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
btnAttributes: TButton;
btnFromNodes: TButton;
procedure FormCreate(Sender: TObject);
procedure btnAttributesClick(Sender: TObject);
procedure btnFromNodesClick(Sender: TObject);
public
XMLDoc : IXMLDOMDocument;
procedure PrepareCDS;
procedure LoadFromAttributes;
procedure LoadFromNodes;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
const
scXML =
'<data a1="a" a2="b" a3="c">'#13#10
+ ' <r1>11111</r1>'#13#10
+ ' <r2>22222</r2>'#13#10
+ '</data>';
scRootNodeName = 'data';
procedure TForm1.FormCreate(Sender: TObject);
begin
XmlDoc := CoDOMDocument.Create;
XmlDoc.Async := False;
XMLDoc.loadXML(scXML);
Memo1.Lines.Text := scXML;
end;
procedure TForm1.LoadFromAttributes;
var
PathQuery : String;
NodeList : IXmlDOMNodeList;
Node,
AttrNode : IXmlDomNode;
Attributes : IXMLDOMNamedNodeMap;
Field : TField;
i : Integer;
begin
PrepareCDS;
PathQuery := scRootNodeName;
NodeList := XMLDoc.SelectNodes(PathQuery);
Assert(NodeList.Length > 0);
Node := NodeList.item[0];
Attributes := Node.attributes;
for i := 0 to Attributes.Length - 1 do begin
AttrNode := Attributes.item[i];
Field := TStringField.Create(Self);
Field.Size := 80;
Field.FieldName := AttrNode.nodeName;
Field.DataSet := CDS1;
end;
CDS1.CreateDataSet;
CDS1.Insert;
for i := 0 to Attributes.Length - 1 do begin
AttrNode := Attributes.item[i];
CDS1.Fields[i].Value := AttrNode.nodeValue;
end;
CDS1.Post;
end;
procedure TForm1.LoadFromNodes;
var
PathQuery : String;
NodeList : IXmlDOMNodeList;
Node,
AttrNode : IXmlDomNode;
Field : TField;
i : Integer;
begin
PrepareCDS;
PathQuery := scRootNodeName + '/*';
NodeList := XMLDoc.SelectNodes(PathQuery);
Assert(NodeList.Length > 0);
for i := 0 to NodeList.Length - 1 do begin
Node := NodeList.item[i];
Field := TStringField.Create(Self);
Field.Size := 80;
Field.FieldName := Node.nodeName;
Field.DataSet := CDS1;
end;
CDS1.CreateDataSet;
CDS1.Insert;
for i := 0 to NodeList.Length - 1 do begin
Node := NodeList.item[i];
CDS1.Fields[i].Value := Node.Text;
end;
CDS1.Post;
end;
procedure TForm1.PrepareCDS;
begin
if CDS1.Active then
CDS1.Close;
CDS1.FieldDefs.Clear;
CDS1.Fields.Clear;
end;
procedure TForm1.btnAttributesClick(Sender: TObject);
begin
LoadFromAttributes;
end;
procedure TForm1.btnFromNodesClick(Sender: TObject);
begin
LoadFromNodes;
end;
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,所有这些都非常简单,只需要熟悉MS XML解析器和XPath的使用(尽管在这种情况下,XML结构非常简单,您实际上不需要使用XPath来实现它) .
在您的情况下,它不适用,但如果您的XML结构事先得到修复,您可以使用Delphi附带的实用程序XmlMapper来定义映射文件,将其转换为TClientDataSet使用的格式.然后,您可以将TClientDataSet与另一个组件TXmlTransformProvider结合使用,该组件使用转换文件将数据加载到CDS中.富勒细节在这里:
顺便说一下,如果您的.Xml文件实际上有多个<DOCTO>节点,则需要将它们置于根节点下,以便该文件具有有效的XML结构.
| 归档时间: |
|
| 查看次数: |
4725 次 |
| 最近记录: |