我有一个大的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功能。
下载截图
我应该改变什么来修复我的问题并且只在我的3个字符串列表中保存正确的字符串?
答案 0 :(得分:6)
也许你应该考虑使用IXMLDocument接口将XML文件加载到数据结构中,然后填充你的字符串列表。
答案 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的可怕方法。我强烈建议您阅读已经执行此操作的项目中的一些源代码,以便更好地了解您应该如何解决问题。一些例子可能是: