【问题标题】:Delphi XE & OmniXML: Using SelectNode()?Delphi XE 和 OmniXML:使用 SelectNode()?
【发布时间】:2011-04-01 13:17:55
【问题描述】:

我有以下 XML sn-p 作为我正在使用最新的 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>

我目前有一个指向&lt;ShipTo&gt; 节点的变量,并且想要选择&lt;Name&gt; 节点的内容。我正在使用以下代码,但 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 将选择单个节点,可能不止一层。肯定有一个&lt;Name&gt; 节点。即使尝试通过XPathSelect(Node1, 'Name'); 查找节点也会返回一个空列表。我是否以某种方式错误地使用了 OmniXML?是否可以在不先选择&lt;Address&gt; 节点的情况下到达&lt;Name&gt; 节点?

【问题讨论】:

    标签: xml delphi delphi-xe omnixml


    【解决方案1】:

    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;
    

    【讨论】:

    • 我真的不想一直到文档级别,我想深入到我已经拥有的节点下。
    【解决方案2】:

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

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

    Node2 := SelectNode(Node, 'Address/Name');
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-09
      • 1970-01-01
      • 2011-12-14
      • 1970-01-01
      相关资源
      最近更新 更多