我使用最新的OmniXML快照处理一个较大的XML文件,其中包含以下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吗?是否可以在不首先选择<Address>节点的情况下访问<Name>节点?
发布于 2011-04-01 22:40:43
如果您在前面放置双斜杠字符,则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;发布于 2011-04-02 01:17:46
我发现我做错了什么:我必须指定整个相对路径,而不仅仅是我想要的孙子节点的名称。
在上面的ProcessXML示例中,我必须像这样填写Node2:
Node2 := SelectNode(Node, 'Address/Name');使用XPath,我必须通过XPathSelect(Node, 'Address/Name');找到它
https://stackoverflow.com/questions/5513917
复制相似问题