首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi XE & OmniXML:使用SelectNode()?

Delphi XE & OmniXML:使用SelectNode()?
EN

Stack Overflow用户
提问于 2011-04-01 21:17:56
回答 2查看 2.4K关注 0票数 3

我使用最新的OmniXML快照处理一个较大的XML文件,其中包含以下XML片段:

代码语言:javascript
复制
<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>节点的内容。我正在使用下面的代码,但是Node2Nil上...

代码语言:javascript
复制
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吗?是否可以在不首先选择<Address>节点的情况下访问<Name>节点?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-01 22:40:43

如果您在前面放置双斜杠字符,则SelectNode运行良好:

代码语言:javascript
复制
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也可以很好地工作:

代码语言:javascript
复制
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;
票数 2
EN

Stack Overflow用户

发布于 2011-04-02 01:17:46

我发现我做错了什么:我必须指定整个相对路径,而不仅仅是我想要的孙子节点的名称。

在上面的ProcessXML示例中,我必须像这样填写Node2

代码语言:javascript
复制
Node2 := SelectNode(Node, 'Address/Name');

使用XPath,我必须通过XPathSelect(Node, 'Address/Name');找到它

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5513917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档