I'm trying to locate the value for <Link role="self">
in the following XML file using a XPath query:
<?xml version="1.0" encoding="utf-8"?>
<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.microsoft.com/search/local/ws/rest/v1">
<Copyright>Copyright © 2011 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.</Copyright>
<BrandLogoUri>http://spatial.virtualearth.net/Branding/logo_powered_by.png</BrandLogoUri>
<StatusCode>201</StatusCode>
<StatusDescription>Created</StatusDescription>
<AuthenticationResultCode>ValidCredentials</AuthenticationResultCode>
<TraceId>ID|02.00.82.2300|</TraceId>
<ResourceSets>
<ResourceSet>
<EstimatedTotal>1</EstimatedTotal>
<Resources>
<DataflowJob>
<Id>ID</Id>
<Link role="self">https://spatial.virtualearth.net/REST/v1/dataflows/Geocode/ID</Link>
<Status>Pending</Status>
<CreatedDate>2011-03-30T08:03:09.3551157-07:00</CreatedDate>
<CompletedDate xsi:nil="true" />
<TotalEntityCount>0</TotalEntityCount>
<ProcessedEntityCount>0</ProcessedEntityCount>
<FailedEntityCount>0</FailedEntityCount>
</DataflowJob>
</Resources>
</ResourceSet>
</ResourceSets>
</Response>
I was shown an XPath query in a previous post, but I keep getting a unassigned iNode
in the following code.
function TForm1.QueryXMLData(XMLFilename, XMLQuery: string): string;
var
iNode : IDOMNode;
Sel: IDOMNodeSelect;
begin
try
XMLDoc.Active := False;
XMLDoc.FileName := XMLFilename;
XMLDoc.Active := True;
Sel := XMLDoc.DOMDocument as IDomNodeSelect;
Result := '';
iNode := Sel.selectNode('Link[@role = "self"]');
if Assigned(iNode) then
if (not VarisNull(iNode.NodeValue)) then
Result := iNode.NodeValue;
XMLDoc.Active := False;
Except on E: Exception do
begin
MessageDlg(E.ClassName + ': ' + E.Message, mtError, [mbOK], 0);
LogEvent(E.Message);
end;
end;
end;
What can I try to resolve this?
If you want to locate Link anywhere in the document, you’ll have to prefix it with //
; like this:
iNode := Sel.selectNode('//Link[@role = "self"][3]');
This will start searching at the root of the document, and traverse the entire document, looking for a node called Link
matching the specified criteria.
See here for more operators: http://msdn.microsoft.com/en-us/library/ms256122.aspx
Note that, as Runner suggests, you can also query the full XML path. This will be faster than the //
operator, since it won’t have to blindly search every node.
Edit: Why are you requesting the third matching node (the [3]
bit)? AFAICS, there’s only one; if your real document does have more, and you’re certain you want the third, then it’s OK. Otherwise, remove the [3]
query.
Also, depending on the XML implementation you’re using (vendor and version), you also might have to specify the XML namespace. In MSXML 4 thru 6 (IIRC), you’d have to use
XMLDoc.setProperty('SelectionNamespaces', 'xmlns:ns="http://schemas.microsoft.com/search/local/ws/rest/v1"');
This would mean using that prefix in your queries as well:
iNode := Sel.selectNode('//ns:Link[@role = "self"][3]');
You should write it like this:
iNode := Sel.selectNode('//Link[@role = "self"]');
which will get you the first Link node in the document with attribute role="self" (even if there is more than one).
Or you can go the absolute path:
iNode := Sel.selectNode('/Response/ResourceSets/ResourceSet/Resources/DataflowJob/Link[@role = "self"]');
or even something in between
iNode := Sel.selectNode('//Resources/DataflowJob/Link[@role = "self"]');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With