本文介绍了德尔福XE& OmniXML:使用SelectNode()吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用最新的OmniXML快照处理的较大XML文件中,有以下XML代码段:

I've got the following XML snippet as part of a larger XML file that I'm processing using the latest OmniXML snapshot:

<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 ...

I've currently got a variable pointing to the <ShipTo> node, and want to select the contents of the <Name> node. I'm using the following code, but Node2 is coming up 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 没有?根据 OmniXMLUtils.pas 中的帮助, SelectNode 将选择一个节点,该节点可能在以下一级以上。肯定有一个< Name> 节点。即使尝试通过 XPathSelect(Node1,‘Name’); 查找节点,也会返回一个空列表。我使用OmniXML是否以某种方式出错?可以在不首先选择< Address> 节点的情况下进入< Name> 节点吗?

Why is Node2 Nil? According to the help in OmniXMLUtils.pas, SelectNode will select a single node possibly more than one level below. There's definitely a <Name> node. Even trying to find the node via XPathSelect(Node1, 'Name'); returns an empty list. Am I using OmniXML wrong somehow? Is it possible to get to the <Name> node without first selecting the <Address> node?

推荐答案

SelectNode 可以很好地工作,如果您将双斜杠字符放在前面:

SelectNode works fine, if you put double-slash characters in front:

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也可以正常工作:

If you prefer, XPath works fine as well:

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;

这篇关于德尔福XE&amp; OmniXML:使用SelectNode()吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 00:35