Чтение из XML на основе нескольких атрибутов
У меня есть XML в следующем формате:
<Accounts>
<Account ID="1" City="Bangalore" Amount="2827561.95" />
<Account ID="225" City="New York" Amount="12312.00" />
<Account ID="236" City="London" Amount="457656.00" />
<Account ID="225" City="London" Amount="23462.40" />
<Account ID="236" City="Bangalore" Amount="2345345.00" />
</Accounts>
Здесь то, что делает аккаунт уникальным, это комбинация атрибутов ID
а также City
,
Как я читаю Amount
однозначно? Как мне прочитать сумму за комбинацию ID
а также City
атрибуты?
Например, мне нужно получить Amount
за счет ID=225
а также City=London
, Если я использую код как
Node.GetAttribute('ID')=225
это всегда дает мне первый узел с ID=225
Благодарю вас.
2 ответа
Решение
Попробуйте с XPath, используя это предложение ./Accounts/Account[@ID="225"][@City="London"]
найти узел.
Попробуйте этот образец
{$APPTYPE CONSOLE}
uses
MSXML,
SysUtils,
ActiveX,
ComObj;
Const
XmlStr =
' <Accounts>'+
' <Account ID ="1" City="Bangalore" Amount="2827561.95"/>'+
' <Account ID="225" City="New York" Amount="12312.00"/>'+
' <Account ID="236" City="London" Amount="457656.00"/>'+
' <Account ID="225" City="London" Amount="23462.40"/>'+
' <Account ID="236" City="Bangalore" Amount="2345345.00"/>'+
'</Accounts>';
procedure Test;
Var
XMLDOMDocument : IXMLDOMDocument;
XMLDOMNode : IXMLDOMNode;
begin
XMLDOMDocument:=CoDOMDocument.Create;
XMLDOMDocument.loadXML(XmlStr);
XMLDOMNode := XMLDOMDocument.selectSingleNode(Format('./Accounts/Account[@ID="%s"][@City="%s"]', ['225', 'London']));
if XMLDOMNode<>nil then
Writeln(Format('Amount %s',[String(XMLDOMNode.attributes.getNamedItem('Amount').Text)]));
end;
begin
try
CoInitialize(nil);
try
Test;
finally
CoUninitialize;
end;
except
on E:EOleException do
Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
on E:Exception do
Writeln(E.Classname, ':', E.Message);
end;
Writeln('Press Enter to exit');
Readln;
end.
function getAmount(Id, City: string): string;
begin
Result := ''
aNode := xmldocument1.DocumentElement.ChildNodes['Accounts'];
for i := 0 to ChildNodes.Count do
with aNode.Nodes[i] do
if (Attributes['ID'] = Id) and (Attributes['City'] = City) then
begin
Result:= Attributes['Amount'];
Break;
end;
end;
end;