如何在Inno Setup中根据子标签的值选择XML标签

时间:2017-06-02 19:25:20

标签: xml inno-setup pascal pascalscript

我试图搜索文本" LIBRA ESTERLINA"在XML元素的子元素中,并检索其他子元素的值。但我的查询没有产生任何结果。

我的代码基于responseHow to read multiple XML nodes? (Inno Setup)responseXPath: 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;

以下是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 个答案:

答案 0 :(得分:1)

请记住,我已经建议您将此问题与您的需求更加匹配:
XPath to select element based on childs child value

所以,你的XPath应该是:

XMLNodeList :=
  XMLDocument.SelectNodes('//listaMonedas/item[moneda/text()="LIBRA ESTERLINA"]');

意思是,您要选择item标记,其中包含带有moneda文字的LIBRA ESTERLINA子标记。

另外,由于您只想要一场比赛(不是吗?),您应该使用SelectSingleNode并且您的代码会更加简单:

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);