Delphi。如何解析这个xml?

时间:2016-11-15 15:07:47

标签: xml delphi

我有这个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>

我试图逐个读取VAT个节点以提取它们的Percent值,但它会在不读取第一个节点的情况下进入第二个节点。这是我的代码,我不知道问题出在哪里:

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;

我正在考虑使用这个CODE节点值,但我不知道怎么做?

2 个答案:

答案 0 :(得分:2)

当第二个循环使用aDoc.Root.NodeCount时,它应该使用aNode.NodeCountaDoc.Root.NodeCount为2,但每个VAT中有两个以上的节点,而Percent超出了每个VAT中的第二个节点,因此您的第二个循环将永远不会看到Percent值。

尝试更像这样的东西:

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;

可替换地:

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;

可替换地:

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;

答案 1 :(得分:1)

使用&#34; XML数据绑定向导&#34; Delphi附带的。 Instructions here

此工具生成一个解析源文件的单元。 使用此单元,这样的简单代码可以为您提供不同增值税元素的百分比。

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;