2016-11-15 82 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;