xml - 德尔福 XE 和 OmniXML : Using SelectNode()?

标签 xml delphi delphi-xe omnixml

我得到了以下 XML 片段,作为我正在使用最新的 OmniXML 快照进行处理的较大 XML 文件的一部分:

<OrderRequestHeader>
<!-- snipped XML bits here -->
<ShipTo>                                                        
    <Address addressID="">                                      
        <Name xml:lang="en">SOME COMPANY</Name>        
        <PostalAddress name="default">                          
            <DeliverTo>John Doe</DeliverTo>                  
            <Street>123 Any St</Street>                  
            <City>Nowhere</City>                              
            <State>AK</State>                                   
            <PostalCode>99999</PostalCode>                      
            <Country isoCountryCode="US">United States</Country>
        </PostalAddress>                                        
        <Email/>                                                
        <Phone>                                                 
            <TelephoneNumber>                                   
                <CountryCode isoCountryCode=""/>                
                <AreaOrCityCode/>                               
                <Number></Number>                               
            </TelephoneNumber>                                  
        </Phone>                                                
    </Address>                                                  
</ShipTo>
<!-- more XML stuff follows -->
</OrderRequestHeader>

我目前有一个变量指向 <ShipTo>节点,并要选择 <Name> 的内容节点。我正在使用以下代码,但是 Node2即将推出Nil ...

procedure ProcessXML;
var
    Node1, Node2: IXMLNode;

begin
    Node1 := FindNode(OrderHeader, 'ShipTo');
    // the above is working.  Node points to the <ShipTo> node
    Node2 := SelectNode(Node1, 'Name');
    // the above line doesn't work.  Node2 is Nil
end;

为什么是Node2 Nil ?根据OmniXMLUtils.pas中的帮助, SelectNode将选择一个可能比下面不止一级的节点。肯定有一个<Name>节点。甚至试图通过 XPathSelect(Node1, 'Name'); 找到节点返回一个空列表。我是否以某种方式错误地使用了 OmniXML?是否可以调用 <Name>节点,无需先选择 <Address>节点?

最佳答案

SelectNode 工作正常,如果您在前面放置双斜杠字符:

var
  FXMLDocument: IXMLDocument;

// Somewhere along the line
  FXMLDocument := CreateXMLDocument
  XMLLoadFromFile(FXMLDocument, 'WhateverFile.xml');
  // or XMLLoadFromAnsiString(FXMLDocument, SomeStringVar);


var
  QryNode, Node: IXMLNode;
begin
  QryNode := FXMLDocument.DocumentElement;
  Node := SelectNode(QryNode, 'ShipTo');
  if Assigned(Node) then
  begin
    QryNode := SelectNode(Node, '//Name');
    if Assigned(QryNode) then
      ShowMessage('ShipTo Name is ' + QryNode.FirstChild.Text)
    else
      ShowMessage('Name not found');
  end;
end;

如果您愿意,XPath 也可以正常工作:

implementation

var
  FXMLDocument: IXMLDocument;

// Somewhere along the line
  FXMLDocument := CreateXMLDocument
  XMLLoadFromFile(FXMLDocument, 'WhateverFile.xml');
  // or XMLLoadFromAnsiString(FXMLDocument, SomeStringVar);

function GetShipTo: string;
var
  QryNode: IXMLNode;
  Node: IXMLNode;
  NodeList: IXMLNodeList;
begin
  Result := '';
  QryNode := FXMLDocument.DocumentElement;  

  // The following also work:
  // '//Address/Name'
  // '//Name'
  NodeList := XPathSelect(QryNode, '//ShipTo/Address/Name');
  if NodeList.Length > 0 then
    QryNode := NodeList.Item[0]
  else
    QryNode := nil;
  if Assigned(QryNode) then
    Result := QryNode.FirstChild.Text; // Now has 'SOME COMPANY'
end;

关于xml - 德尔福 XE 和 OmniXML : Using SelectNode()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5513917/

相关文章:

Delphi XE2 VCL样式,更改窗口图标直到RecreateWnd才在标题栏上更新

delphi - 在主机应用程序和 DLL 之间传递包含方法的记录

windows - 如何在 Delphi 中处理自定义组件中的箭头键?

windows - Delphi XE 和使用 OnKeyDown 捕获箭头键

java - 如何使用 Java 和 XPath 列出节点文本和属性?

ruby-on-rails - 如何在 Rails 中将 XML 转换为散列?

c++ - 如何从核心转储遍历 xerces-c DOMDocument?

delphi - 如何在 delphi 上实现 OutlookApp.Onquit 事件并进行兑换并避免应用程序繁忙时挂起 Outlook

Delphi XE [DCC fatal error ] F2084 内部错误 : DBG2886

xml - 是否有用于表达复杂搜索查询的 XML 元语言?