复制&使用stringlist复制无法正常工作

时间:2013-06-24 13:49:04

标签: xml delphi delphi-xe3 tstringlist

我有一个大的xml文件,我想保存每个id,source&成功导入到字符串列表后生成的字符串列表中的目标生成对mysql的查询。

这是我的xml的片段:

xliff version="1.1">
 <file original="Xliff Demo" source-language="EN" target-language="DE" datatype="html">
 <header>
 <skl>
 <external-file uid="017dbcf0-c82c-11e2-ba2b-005056c00008" href="skl\simple.htm.skl"/>
 </skl>
 </header>
 <body>
 <trans-unit id="00ffmnpB5wBV5KFqBxuHLi4fwJvvuB">
 <source xml:lang="EN">1lnRUfBBeHtbS96uULSht42VNMN7XE4qt9JrOcWhtoTuhnbAQ9</source>
 <target xml:lang="DE">zZvOLJfLCy9oP5GQYfEqw5LAeC2ESAxRmVe1JyQdmJ1eG2jz1N</target>
 <note/></trans-unit>
 <trans-unit id="00kjUwy1rJ54bEGYp7XZvtBiY32pmj">
 <source xml:lang="EN">HXOQLUWkfJg206vRw8lyWhCWChOacVxbMukfQ0HUdNHSI18GG4</source>
 <target xml:lang="DE">8dsX38mezeZ0w0w37LI66CDRuI8gBD23zT5KR4iqYNv3IGUgH0</target>
 <note/></trans-unit>
 <trans-unit id="00kk3Af8SFpHyelAaYrgK58b9GbIDj">
 <source xml:lang="EN">wQFxZiCiRsSNWs20G4WXAmDBRdRL6fcrrJnCgtbiXGSfHzpYrT</source>
 <target xml:lang="DE">oFVTUdPkExOhISYofIImLsnVKd3NSZg32tyeP5iRxRZdmuYQDy</target>
 <note/></trans-unit>
 <trans-unit id="00Ky2dmDU9wGTWBnJxeL9b9gkts5UQ">
 <source xml:lang="EN">nHQcjAW02lWe0SyOhqGtyqUhpwQ8qgWX3rUynMRf4BDHfVdHOC</source>
 <target xml:lang="DE">0CURp1dcZydB1V2rEZ1lnOhmYufOYbrLbh84e1ZnALlzZPVq4F</target>
 <note/></trans-unit>
 <trans-unit id="00pMSFlBfA3bJ8Xy9I78wz6XisPYcV">
 <source xml:lang="EN">IuhtaVnZtF67nxKz5dbmuy8BEMTs2X1120FzDtIplKF2Me5AsQ</source>
 <target xml:lang="DE">1BGSJQDZBm4UW974pucnX3XHuYOQYpC7nTcIH01rbKlOkVi9bo</target>
 <note/></trans-unit>
 <trans-unit id="012w2kb2d1Lo6NbJLE0BawThzsSuCJ">
 <source xml:lang="EN">0RoniOGZ7V7WTF1YQg59B8jBhRxnLVXscC1LOGPzKPYRs76oIz</source>
 <target xml:lang="DE">gyw15fkHTni2aUGWI5qiPHEz8vsJJJsW4OOqKwGYL1qzfUVfLO</target>
 <note/></trans-unit>
...
..
..

所以我尝试在单独的字符串列表中保存trans-unit id,source xml:lang“EN”,target xml:lang =“DE”的每个条目,但只保存值。

这是我的代码:

{ -----------  Import Procedure ------------ }
procedure TForm2.Button2Click(Sender: TObject);
var
  xmlFile, idList, sourceList, targetList: TStringList; // StringListe wo die Xml Datei eingelesen wird
  i: Integer;
  id, source, target: String;
  idTmp, idTmp2, sourceTmp, sourceTmp2, targetTmp, targetTmp2: Integer;
begin
  try
    xmlFile := TStringList.Create;
    idList := TStringList.Create;
    sourceList := TStringList.Create;
    targetList := TStringList.Create;

    if OpenDialog1.Execute then
      xmlFile.LoadFromFile(OpenDialog1.FileName);

      {Debug}
        //ShowMessage(IntToStr(XmlFile.Count));   Ausgabe der Zeilenlänge
        //ShowMessage(XmlFile[8]);                // Ausgabe der Zeile 8
      {/Debug}

      for i := 0 to xmlFile.Count-1 do // Über alle Zeilen der StringList gehen und folgendes tun:
        begin // Code pro Zeile

          {id}
          idTmp  := Pos('<trans-unit id="', xmlFile.Strings[i])+16;  //  Sucht nach trans-unit id   (16 ist die Anzahl der Länge vom Suchstring in dem Fall trans-unit id 16 Stellen lang
          if idTmp > 5 then // Überprüfen ob was gefunden wurde (Ungleich 0)
          begin
            idTmp2 := Pos('"', xmlFile.Strings[i], idTmp); // Ermittelt die Position vom Ende des Strings (")
            idList.Add(Copy(xmlFile.Strings[i], idTmp, idTmp2-idTmp));
          end;

          {source}
          sourceTmp  := Pos('<source xml:lang="EN">', xmlFile.Strings[i])+22;
          if sourceTmp > 5 then // Überprüfen ob was gefunden wurde (Ungleich 0)
          begin
            sourceTmp2 := Pos('<', xmlFile.Strings[i], sourceTmp); // Ermittelt die Position vom Ende des Strings (")
            sourceList.Add(Copy(xmlFile.Strings[i], sourceTmp, sourceTmp2-sourceTmp));
          end;

          {target}
          targetTmp  := Pos('<target xml:lang="DE">', xmlFile.Strings[i])+22;
          if targetTmp > 5 then // Überprüfen ob was gefunden wurde (Ungleich 0)
          begin
            targetTmp2 := Pos('<', xmlFile.Strings[i], targetTmp); // Ermittelt die Position vom Ende des Strings (")
            targetList.Add(Copy(xmlFile.Strings[i], targetTmp, targetTmp2-targetTmp));
          end;
        end;

      StartPerformance;
      UniConnection1.Open;
  finally
    ListBox1.items.assign(idList);
    ListBox2.items.assign(sourceList);
    ListBox3.items.assign(targetList);
    ShowMessage('Import in StringListen fertiggestellt.');
    xmlFile.Free;
    idList.Free;
    sourceList.Free;;
    targetList.Free;
  end;
end;

但它不像我想要的那样工作。我的问题是,它在stringlist和其他垃圾中也保存了空行。我真的没有找到我的错误,这是我第一次使用这个拷贝/ pos功能。

下载截图

enter image description here

我应该改变什么来修复我的问题并且只在我的3个字符串列表中保存正确的字符串?

2 个答案:

答案 0 :(得分:6)

也许你应该考虑使用IXMLDocument接口将XML文件加载到数据结构中,然后填充你的字符串列表。

此处发布了一个示例:https://stackoverflow.com/a/8651934/2207071

答案 1 :(得分:3)

这里:

idTmp  := Pos('<trans-unit id="', xmlFile.Strings[i])+16;  
if idTmp > 5 then 
  ...

idTmp将始终大于5 - 无论如何都会向其添加16并且它总是返回正值(如果不匹配则为零)。

这里最简单的改变是:

 idTmp  := Pos('<trans-unit id="', xmlFile.Strings[i]);  
 if idTmp > 0 then begin //Pos returns 0 if no match found
   idTmp := idTmp + 16;
   idTmp2 := PosEx('"', xmlFile.Strings[i], idTmp); 
   idList.Add(Copy(xmlFile.Strings[i], idTmp, idTmp2-idTmp));
 end;

其他两个街区的变化将以类似的方式进行。

你会注意到我在这里使用了StrUtils.PosEx idTmp2 - 我不知道你的代码是如何使用Pos为第二个函数编译的......

修改

好的,看起来Pos在XE3中被更改为包含偏移量过载。如果性能是你的目标(从评论看来),你应该读一读:

http://qc.embarcadero.com/wc/qcmain.aspx?d=111103

此外,我认为这可能非常重要,这实际上是一种解析XML的可怕方法。我强烈建议您阅读已经执行此操作的项目中的一些源代码,以便更好地了解您应该如何解决问题。一些例子可能是: