2016-11-15 81 views
0

我有這樣的XML:Delphi.How解析這個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; 

我想使用此代碼節點值,但我不知道怎麼樣?

+0

它不是,它* ...進入第二個節點,而閱讀第一個增值稅節點*您似乎將來自兩個節點的百分比值分配給同一個唯一的「XReportInfo.PercTvaA」。將一個斷點放在'for i:= 0 to aDoc.Root.NodeCount - 1 do'上,然後用** F8 **逐行逐行執行代碼,看看如何覆蓋第一個節點的值,從第二個價值。 –

回答

1

使用Delphi自帶的「XML數據綁定向導」。 Instructions here

這個工具生成一個單元來解析源文件。 有了這個單位,像這樣一個簡單的代碼,給你不同VAT元素的百分比。

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; 
+1

「XML數據綁定向導」不包含Delphi的所有版本(SKU),對於小型XML文件而言,這通常是過量的。你還應該包括一個替代方案。 –

2

你的第二個循環的時候應該使用aNode.NodeCount它,而不是使用aDoc.Root.NodeCountaDoc.Root.NodeCount是2,但每個VAT中有多於2個節點,並且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;