如何在Delphi中使用查询XML文件?

4
我是 Delphi 的新手,这是我想做的事情。我有一个格式如下的 XML 文件:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Row>
        <Designation>1234102</Designation>
        <Inner>5.412</Inner>
        <Outer>3.588</Outer>
        <Spin>4.732</Spin>
        <Cage>0.399</Cage>
    </Row>
    <Row>
        <Designation>1342153</Designation>
        <Inner>5.916</Inner>
        <Outer>4.084</Outer>
        <Spin>5.277</Spin>
        <Cage>0.408</Cage>
    </Row>
    ........
</Data>

我想用Delphi查询它。例如:我想要 的数据,其中 是1342153。最好和最简单的解决方案是什么?
提前感谢您的示例和解释。

什么是查询?为什么需要那个值而不是其他值?您是否还需要其他值?哪些值,以及为什么和多久需要一次?有几种解决方案,例如DOM解析器、SAX解析器、XPATH、记录数组反序列化-但不知道您实际上需要用XML做什么。http://catb.org/esr/faqs/smart-questions.html - Arioch 'The
请编辑您的问题,并在下面添加包含Delphi语言版本的标签。 - Arioch 'The
我的XML文件大约有6000个“行”,我想读取整个行而不仅仅是指定的内容。 - user2572823
4个回答

3

正如其他人建议的那样,您可以使用XPath查找特定值,在本例中使用此表达式 /Data/Row/Designation[text()="1342153"] 将定位包含Designation中值为1342153的节点。

请尝试此示例代码

{$APPTYPE CONSOLE}

{$R *.res}

uses
  MSXML,
  SysUtils,
  ActiveX,
  ComObj;

Const
 XmlStr =
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'+
'<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'+
'    <Row>'+
'        <Designation>1234102</Designation>'+
'        <Inner>5.412</Inner>'+
'        <Outer>3.588</Outer>'+
'        <Spin>4.732</Spin>'+
'        <Cage>0.399</Cage>'+
'    </Row>'+
'    <Row>'+
'        <Designation>1342153</Designation>'+
'        <Inner>5.916</Inner>'+
'        <Outer>4.084</Outer>'+
'        <Spin>5.277</Spin>'+
'        <Cage>0.408</Cage>'+
'    </Row>'+
'</Data>';

procedure Test;
Var
  XMLDOMDocument  : IXMLDOMDocument;
  XMLDOMNode      : IXMLDOMNode;
begin
  XMLDOMDocument:=CoDOMDocument.Create;
  XMLDOMDocument.loadXML(XmlStr);
  XMLDOMNode := XMLDOMDocument.selectSingleNode('/Data/Row/Designation[text()="1342153"]');
  if XMLDOMNode<>nil then
   Writeln('Found');
end;

begin
 try
    CoInitialize(nil);
    try
      Test;
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.

3
我假设一旦您找到了“Designation”,您还想阅读与其相关的其他条目(“Inner”,“Outer”,“Spin”和“Cage”)。XPath是解决这个问题的完美方案。我的示例使用一个新表单,只有一个TMemo和TButton,并添加了一个Button1.OnClick事件处理程序:
uses
  MSXML, ComObj, ActiveX;

const
  XMLText =  '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
             '<Data>' +
              '<Row>' +
                  '<Designation>1234102</Designation>' +
                  '<Inner>5.412</Inner>' +
                  '<Outer>3.588</Outer>' +
                  '<Spin>4.732</Spin>' +
                  '<Cage>0.399</Cage>' +
              '</Row>' +
              '<Row>' +
                 '<Designation>1342153</Designation>' +
                 '<Inner>5.916</Inner>' +
                  '<Outer>4.084</Outer>' +
                  '<Spin>5.277</Spin>' +
                  '<Cage>0.408</Cage>' +
              '</Row>' +
          '</Data>';

procedure TForm1.Button1Click(Sender: TObject);
var
  XMLDoc: IXMLDOMDocument;
  Node, SibNode: IXMLDOMNode;
begin
  Memo1.Clear;
  XMLDoc := CoDOMDocument.Create;
  XMLDoc.loadXML(XMLText);

  // Select the node with the Designation you want.
  Node := XMLDoc.selectSingleNode('//Designation[text()="1342153"]');
  if Assigned(Node) then
  begin
    Memo1.Lines.Add('Found it.');
    Memo1.Lines.Add(Node.nodeName + ' = ' + Node.firstChild.nodeValue);

    // Read all the nodes at the same level as the Designation
    SibNode := Node.nextSibling;
    while SibNode <> nil do
    begin
      Memo1.Lines.Add(SibNode.nodeName + ' = ' + 
                      SibNode.firstChild.nodeValue);
      Sib := Sib.nextSibling;
    end;
  end;
end;

如果您想获取所有<Row>元素并循环遍历它们包含的信息,可以使用以下方法(在上面的测试应用程序中添加第二个按钮,并将其用于Button2.OnClick处理程序):
procedure TForm1.Button2Click(Sender: TObject);
var
  XMLDoc: IXMLDOMDocument;
  NodeList: IXMLDOMNodeList;
  Node, SibNode: IXMLDOMNode;
  i: Integer;
begin
  Memo1.Clear;
  XMLDoc := CoDOMDocument.Create;
  XMLDoc.loadXML(XMLText);
  NodeList := XMLDoc.selectNodes('/Data/Row');
  if Assigned(NodeList) then
  begin
    for i := 0 to NodeList.length - 1 do
    begin
      Node := NodeList.item[i];
      SibNode := Node.firstChild;
      while Assigned(SibNode) do
      begin
        Memo1.Lines.Add(SibNode.nodeName + ' = ' + 
                        SibNode.firstChild.nodeValue);
        SibNode := SibNode.nextSibling;
      end;
    end;
    // Add a blank line between groupings for readability
    Memo1.Lines.Add('');
  end;
end;

1

在Delphi中查询xml时,IXMLDocument和XPath是您的好帮手。您可以找到许多相关资源,例如XPath and TXmlDocument


0

如果您想从xml中查询数据,我建议您使用此处记录的XML转换http://docwiki.embarcadero.com/RADStudio/XE4/en/Converting_XML_Documents_into_Data_Packets

这将把您的xml映射到一个ClientDataSet,然后您可以按照您想要的列筛选记录,或者您可以使用DataBinding Wizard,文档中有解释,网址为http://docwiki.embarcadero.com/RADStudio/XE4/en/Using_the_XML_Data_Binding_Wizard

对于其他处理xml的方法,您可以查看文档的主索引,网址为http://docwiki.embarcadero.com/RADStudio/XE4/en/Working_with_XML_documents_Index


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接