【问题标题】:FindNode with two equals nodeFindNode 有两个等于节点
【发布时间】:2016-08-15 19:47:29
【问题描述】:

我创建了一个根据 MySQL 行生成 XML 的 WebService,结果是这样的:

<DB>
    <CONFIG>
        <ID>1</ID>
        <CODAUTORIZACAO>12345</CODAUTORIZACAO>
        <CODUSUARIO>12345</CODUSUARIO>
        <CODEMPRESA>12345</CODEMPRESA>
        <NOMEEMPRESA>TESTE</NOMEEMPRESA>
    </CONFIG>
    <COLETEIROS>
        <ID>1</ID>
        <CODIGO>123</CODIGO>
        <NOME>teste</NOME>
        <PRECOCX>1</PRECOCX>
        <PRECOKG>1</PRECOKG>
        <PRECOCS>1</PRECOCS>
    </COLETEIROS>
    <COLETEIROS>
        <ID>2</ID>
        <CODIGO>135</CODIGO>
        <NOME>ab</NOME>
        <PRECOCX>12</PRECOCX>
        <PRECOKG>321</PRECOKG>
        <PRECOCS>12</PRECOCS>
    </COLETEIROS>
</DB>

如果您看到,这个 XML 有两个同名的节点 "COLETEIROS",但是当我找到具有 XMLDocument.DocumentElement.ChildNodes.FindNode('COLETEIROS') 的节点时> 我只能看到第一个。有没有办法在存在时找到 FindNode?我正在尝试用这些值填充组合框,但我是 XMLDocument 的新手。

感谢您的帮助!

【问题讨论】:

  • 迭代节点
  • 我没有发现任何关于 Iterate to Delphi XMLDocument 的信息,仅适用于 C# 和 Delphi NativeXML,但在 Delphi XE10 NativeXML 中被替换为 XMLDocument 并且我不知道等效代码,因为我都不知道哈哈:/
  • 所有 XML 库都允许枚举
  • 感谢您的帮助!我找到了另一种方法,但你也提供了帮助

标签: xml delphi


【解决方案1】:

如果有多个子节点 FindNode 将只返回任何指定节点中的第一个。 FindNode 返回一个 IXMLNode

要获取具有指定名称的所有节点的列表,请使用 IDOMNode 接口的 selectNodes() 方法。 selectNodes() 返回一个 IDOMNodeList。然后,您可以像往常一样遍历节点列表。

  uses
    XMLDoc,
    XMLDOM,
    XMLIntf;

procedure ExampleUsingSelectNodes;
const
  XML = '<DB>'
      + '    <CONFIG>'
      + '        <ID>1</ID>'
      + '        <CODAUTORIZACAO>12345</CODAUTORIZACAO>'
      + '        <CODUSUARIO>12345</CODUSUARIO>'
      + '        <CODEMPRESA>12345</CODEMPRESA>'
      + '        <NOMEEMPRESA>TESTE</NOMEEMPRESA>'
      + '    </CONFIG>'
      + '    <COLETEIROS>'
      + '        <ID>1</ID>'
      + '        <CODIGO>123</CODIGO>'
      + '        <NOME>teste</NOME>'
      + '        <PRECOCX>1</PRECOCX>'
      + '        <PRECOKG>1</PRECOKG>'
      + '        <PRECOCS>1</PRECOCS>'
      + '    </COLETEIROS>'
      + '    <COLETEIROS>'
      + '        <ID>2</ID>'
      + '        <CODIGO>135</CODIGO>'
      + '        <NOME>ab</NOME>'
      + '        <PRECOCX>12</PRECOCX>'
      + '        <PRECOKG>321</PRECOKG>'
      + '        <PRECOCS>12</PRECOCS>'
      + '    </COLETEIROS>'
      + '</DB>';
var
  doc: TXMLDocument;
  select: IDOMNodeSelect;
  nodes: IDOMNodeList;
begin
  doc := TXMLDocument.Create(nil);
  doc.LoadFromXML(XML);

  select := doc.DocumentElement.DOMNode as IDOMNodeSelect;
  nodes  := select.selectNodes('COLETEIROS');

  // At this point nodes is an IDOMNodeList with length 2 (i.e. contains both COLETEIROS nodes)

  // process the list of nodes here
end;

或者,您可以遍历文档中的每个子节点并测试每个子节点的所需节点名称,并仅处理与您想要的名称匹配的节点。这更冗长,但完全可以与 XMLDoc 接口一起使用,不需要 DOM 支持(这在您的情况下可能很重要,也可能不重要)。

假设在这种情况下示例 XML 文档具有相同的 XML const 声明,手动迭代的代码将类似于:

var
  doc: TXMLDocument;
  node: IXMLDOMNode;
begin
  doc := TXMLDocument.Create(nil);
  doc.LoadFromXML(XML);

  node := doc.DocumentElement.ChildNodes.First;
  while Assigned(node) do
  begin
    if node.NodeName = 'COLETEIROS' then
    begin
      // Do something with this node
    end;
    node := node.NextSibling
  end;
end;

【讨论】:

    【解决方案2】:

    FindNode() 不能用于搜索多个节点。您必须:

    1. 手动遍历所有节点以查找单个 COLETEIROS 节点:

      var
        Node: IXMLNode;
        I: Integer;
      
      for I := 0 to XMLDocument.DocumentElement.ChildNodes.Count-1 do
      begin
        Node := XMLDocument.DocumentElement.ChildNodes[I];
        if Node.LocalName = 'COLETEIROS' then
           ...
      end;
      
    2. 使用 XPath 查询:

      var
        XPath: IDOMNodeSelect;
        Nodes: IDOMNodeList;
        Node: IDOMNode;
        I: Integer;
      
      if Supports(XMLDocument.DocumentElement, IDOMNodeSelect, XPath) then
      begin
        Nodes := XPath.selectNodes('/DB/COLETEIROS');
        for I := 0 to Nodes.length-1 do
        begin
          Node := Nodes[I];
          ...
        end;
      end;
      

    【讨论】:

      猜你喜欢
      • 2020-05-28
      • 2018-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多