如何测试某个XML节点是否存在?

时间:2012-06-15 22:34:24

标签: xml delphi

测试可选节点存在的正确方法是什么?剪下我的XML是:

<Antenna >
  <Mount Model="text" Manufacture="text">
   <BirdBathMount/>
  </Mount>
</Antenna>

但它也可能是:

<Antenna >
  <Mount Model="text" Manufacture="text">
   <AzEl/>
  </Mount>
</Antenna>

Antenna的孩子可能是BirdBath或AzEl,但不是两者......

在Delphi XE中,我尝试过:

 if (MountNode.ChildNodes.Nodes['AzEl'] <> unassigned then //Does not work
 if (MountNode.ChildNodes['BirdBathMount'].NodeValue <> null) then // Does not work
 if (MountNode.BirdBathMount.NodeValue <> null) then  // Does not work

我使用XMLSpy来创建架构和示例XML,并且它们正确解析。我使用Delphi XE来创建绑定,并且它适用于大多数其他组合。

这个必须有一个我忽略的简单答案 - 但是什么? 谢谢......吉姆

4 个答案:

答案 0 :(得分:8)

您可以使用XPath,尝试此示例。

uses
  MSXML;


Var
  XMLDOMDocument  : IXMLDOMDocument;
  XMLDOMNode      : IXMLDOMNode;
begin
  XMLDOMDocument:=CoDOMDocument.Create;
  XMLDOMDocument.loadXML(XmlStr);
  XMLDOMNode := XMLDOMDocument.selectSingleNode('//Antenna/Mount/BirdBathMount');
  if XMLDOMNode<>nil then
    Writeln('BirdBathMount node Exist')
  else
  begin
    XMLDOMNode := XMLDOMDocument.selectSingleNode('//Antenna/Mount/AzEl');
    if XMLDOMNode<>nil then
      Writeln('AzEl node Exist');
  end;
end;

答案 1 :(得分:8)

使用.FindNode。如果节点不存在,则返回nil。

e.g。

xmlNode := MountNode.ChildNodes.FindNode('AzEl');
if Assigned(xmlNode) then
...

答案 2 :(得分:1)

我已成功测试过它。用这个代码。它有点复杂,我需要一个根元素。

XmlFile

<ThisIsTheDocumentElement>
<Antenna >
  <Mount Model="text" Manufacture="text">
   <BirdBathMount/>
  </Mount>
</Antenna>
<Antenna >
  <Mount Model="text" Manufacture="text">
   <AzEl/>
  </Mount>
</Antenna>
</ThisIsTheDocumentElement>

<强> Delphi2010.pas

procedure TForm1.RetrieveDocument;
var
  LDocument: IXMLDocument;
  LNodeElement, LNode,BNode,CNode : IXMLNode;
  I: Integer;
begin
  LDocument := TXMLDocument.Create(nil);
  LDocument.LoadFromFile(XmlFile);
  LNodeElement := LDocument.ChildNodes.FindNode('ThisIsTheDocumentElement');
  if (LNodeElement <> nil) then
  begin
    for I := 0 to LNodeElement.ChildNodes.Count - 1 do
    begin
      LNode := LNodeElement.ChildNodes.Get(I);
       if (LNode <> Nil) AND (LNode.NodeName='Antenna') then begin
          Memo1.lines.Add('Node name: ' + LNode.NodeName);
          BNode:=LNode.ChildNodes.FindNode('Mount');
         if (BNode <> Nil) then CNode:=BNode.ChildNodes.FindNode('AzEl');
            if (CNode <> Nil) then Memo1.lines.Add('found: '+CNode.NodeName) else continue;
       end;
    end;
  end;
end;

<强>输出:

Node name: Antenna
Node name: Antenna
found: AzEl

答案 3 :(得分:0)

对我有用的是:

if (MountNode.ChildNodes.FindNode('AzEl') <> nil) then

我不清楚nil如何响应TXMLDocumnet上的选项设置,例如doAttrNull,但它有效。