问题
I'm trying to search for a text "LIBRA ESTERLINA" in a child element of XML element and retrieve values of others child elements. But my query yields nothing.
My code is based on response from How to read multiple XML nodes? (Inno Setup) and response from XPath: How to select elements based on their value?
function LoadValuesFromXMLMoneda(FileName: string): Boolean;
var
XMLNode: Variant;
XMLNodeList: Variant;
XMLDocument: Variant;
Index: Integer;
id, moneda, dollar, abr, singPlur, caracter : String;
begin
XMLDocument := CreateOleObject('Msxml2.DOMDocument.6.0');
try
XMLDocument.async := False;
XMLDocument.load(FileName);
if (XMLDocument.parseError.errorCode <> 0) then
begin
Log('The XML file could not be parsed. ' + XMLDocument.parseError.reason);
Result := False;
end
else
begin
XMLDocument.setProperty('SelectionLanguage', 'XPath');
XMLNodeList :=
XMLDocument.SelectNodes('//listaMonedas/item/moneda[text()="LIBRA ESTERLINA"]');
for Index := 0 to XMLNodeList.length - 1 do
begin
XMLNode := XMLNodeList.item[Index];
id := XMLNode.SelectSingleNode('id').Text;
moneda := XMLNode.SelectSingleNode('moneda').Text;
dollar := XMLNode.SelectSingleNode('dollar').Text;
abr := XMLNode.SelectSingleNode('abr').Text;
singPlur := XMLNode.SelectSingleNode('singPlur').Text;
caracter := XMLNode.SelectSingleNode('caracter').Text;
MsgBox(id+moneda+dollar+abr+singPlur+caracter,mbInformation,MB_OK);
end;
Result := True;
end;
except
Log('An error occured!' + #13#10 + GetExceptionMessage);
Result := False;
end;
end;
Here is XML
:
<ns1:obtenerMonedasResponse
xmlns:ns1="urn:v1.001" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://www.example.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<listaMonedas xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="tns:WSMoneda[21]">
<item xsi:type="tns:WSMoneda">
<id xsi:type="xsd:integer">1</id>
<moneda xsi:type="xsd:string">LIBRA ESTERLINA</moneda>
<dollar xsi:type="xsd:string">0.7767</dollar>
<abr xsi:type="xsd:string">GBP</abr>
<singPlur xsi:type="xsd:string">LIBRA:LIBRAS</singPlur>
<caracter xsi:type="xsd:string">£</caracter>
<flag16 xsi:type="xsd:string">Base64Img</flag16>
<flag24 xsi:type="xsd:string">Base64Img</flag24>
<flag32 xsi:type="xsd:string">Base64Img</flag32>
</item>
<item xsi:type="tns:WSMoneda">
<id xsi:type="xsd:integer">1</id>
<moneda xsi:type="xsd:string">PESO MEXICANO</moneda>
<dollar xsi:type="xsd:string">18.7000</dollar>
<abr xsi:type="xsd:string">MXN</abr>
<singPlur xsi:type="xsd:string">PESO:PESOS</singPlur>
<caracter xsi:type="xsd:string">$</caracter>
<flag16 xsi:type="xsd:string">Base64Img</flag16>
<flag24 xsi:type="xsd:string">Base64Img</flag24>
<flag32 xsi:type="xsd:string">Base64Img</flag32>
</item>
</listaMonedas>
</ns1:obtenerMonedasResponse>
回答1:
Remember, that I've suggested you this question as a closer match to your needs:
XPath to select element based on childs child value.
So, your XPath should be:
XMLNodeList :=
XMLDocument.SelectNodes('//listaMonedas/item[moneda/text()="LIBRA ESTERLINA"]');
Meaning, that you want to select the item
tag, that contains moneda
child tag with LIBRA ESTERLINA
text.
Also as you expect a single match only (don't you?), you should use SelectSingleNode
and your code will be much simpler:
XMLNode :=
XMLDocument.SelectSingleNode('//listaMonedas/item[moneda/text()="LIBRA ESTERLINA"]');
id := XMLNode.SelectSingleNode('id').Text;
moneda := XMLNode.SelectSingleNode('moneda').Text;
dollar := XMLNode.SelectSingleNode('dollar').Text;
abr := XMLNode.SelectSingleNode('abr').Text;
singPlur := XMLNode.SelectSingleNode('singPlur').Text;
caracter := XMLNode.SelectSingleNode('caracter').Text;
MsgBox(id+moneda+dollar+abr+singPlur+caracter, mbInformation, MB_OK);
来源:https://stackoverflow.com/questions/44336112/how-to-select-xml-tag-based-on-value-of-its-child-tag-in-inno-setup