Vlad Costin
Vlad Costin

Reputation: 61

Delphi.How to parse this xml?

I have this XML :

<NET_TAX_DATABASE DeviceSerialNo="ATH16000038" CreationDate="15/11/2016 13:21">
<VAT>
<Code>02</Code>
<Letter>B</Letter>
<Percent>8%</Percent
<RcptVATAmount>31,11</RcptVATAmount>
</VAT>
<VAT>
<Code>03</Code>
<Descr>CATEG. TVA B</Descr>
<Letter>C</Letter>
<Percent>11%</Percent>
<RcptVATAmount>312,11</RcptVATAmount>
</VAT>
</NET_TAX_DATABASE>

I am trying to read the VAT nodes one by one to extract their Percent values, but it goes to the second node without reading the first node. Here is my code, I don't know where the problem is:

var
  i,j      : Integer;
  aDoc     : TNativeXml;
  aNode    : TXmlNode;
begin
  try
    aDoc := TNativeXml.Create(nil);
    aDoc.LoadFromStream(content);
    aDoc.XmlFormat := xfReadable;
    if Assigned(aDoc.Root) then
    begin
      for i := 0 to aDoc.Root.NodeCount - 1 do
      begin
        if (AnsiUpperCase(aDoc.Root.Nodes[i].Name) = AnsiUpperCase('vat')) then
        begin
          aNode := aDoc.Root.Nodes[i];
          for j := 0 to aDoc.Root.NodeCount - 1 do
          begin
            if (aNode[j].Name = 'Percent') then
            begin
              str                  := aNode[j].ValueUnicode;
              str                  := stringReplace(str, '%','',[rfReplaceAll]);
              XReportInfo.PercTvaA := StrToInt(trim(str));
            end;
          end;
        end;
      end;
    end;
  finally
    aDoc.Free;
  end;
end;

I am thinking to use this CODE node values but i don't know how?

Upvotes: 0

Views: 292

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 595367

Your second loop is using aDoc.Root.NodeCount when it should be using aNode.NodeCount instead. aDoc.Root.NodeCount is 2, but there are more than 2 nodes in each VAT, and Percent is beyond the second node in each VAT, so your second loop will never see either of the Percent values.

Try something more like this instead:

var
  i,j   : Integer;
  aDoc  : TNativeXml;
  aNode : TXmlNode;
begin
  aDoc := TNativeXml.Create(nil);
  try
    aDoc.LoadFromStream(content);
    aDoc.XmlFormat := xfReadable;
    if Assigned(aDoc.Root) then
    begin
      for i := 0 to aDoc.Root.NodeCount - 1 do
      begin
        aNode := aDoc.Root.Nodes[i];
        if SameText(aNode.Name, 'VAT') then
        begin
          for j := 0 to aNode.NodeCount - 1 do
          begin
            if SameText(aNode[j].Name, 'Percent') then
            begin
              str := StringReplace(aNode[j].ValueUnicode, '%', '', [rfReplaceAll]);
              // use str as needed...
              Break;
            end;
          end;
        end;
      end;
    end;
  finally
    aDoc.Free;
  end;
end;

Alternatively:

var
  i,j      : Integer;
  aDoc     : TNativeXml;
  aNode, aPercent : TXmlNode;
begin
  aDoc := TNativeXml.Create(nil);
  try
    aDoc.LoadFromStream(content);
    aDoc.XmlFormat := xfReadable;
    if Assigned(aDoc.Root) then
    begin
      for i := 0 to aDoc.Root.NodeCount - 1 do
      begin
        aNode := aDoc.Root.Nodes[i];
        if SameText(aNode.Name, 'VAT') then
        begin
          aPercent := aNode.NodeByName('Percent');
          if aPercent <> nil then
          begin
            str := StringReplace(aPercent.ValueUnicode, '%', '', [rfReplaceAll]);
            // use str as needed...
          end;
        end;
      end;
    end;
  finally
    aDoc.Free;
  end;
end;

Alternatively:

var
  i,j      : Integer;
  aDoc     : TNativeXml;
  aList    : TList;
  aPercent : TXmlNode;
begin
  aDoc := TNativeXml.Create(nil);
  try
    aDoc.LoadFromStream(content);
    aDoc.XmlFormat := xfReadable;
    if Assigned(aDoc.Root) then
    begin
      aList := TList.Create;
      try
        aDoc.Root.FindNodes('Percent', aList);
        for i := 0 to aList.Count - 1 do
        begin
          aPercent := TXmlNode(aList[i]);
          str := StringReplace(aPercent.ValueUnicode, '%', '', [rfReplaceAll]);
          // use str as needed...
        end;
      finally
        aList.Free;
      end;
    end;
  finally
    aDoc.Free;
  end;
end;

Upvotes: 2

Use "XML Data Binding Wizard" that comes with Delphi. Instructions here.

This tools generate a unit to parse the source file. With this unit, a simple code like this, give you the percent of differents VAT elements.

var
  StockList: IXMLNET_TAX_DATABASEType;
  vat:IXMLVATType;
  i:integer;
begin
  StockList := LoadNET_TAX_DATABASE('sampleXML.xml');
  for I := 0 to (StockList.Count - 1) do begin
    vat := StockList.VAT[i];
    Memo1.Lines.Add(IntToStr(vat.Code) +   ' -- ' + vat.Percent);
  end;
end;

Upvotes: 1

Related Questions