How to select XML tag based on value of its child tag in Inno Setup

浪子不回头ぞ 提交于 2019-12-12 09:21:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!