2016-09-23 58 views
1

我有一個XML文件(實際上是一個XLIFF文件),其中節點具有2個孩子具有相同子節點(未先驗已知的,可以是非常複雜的,併爲每個<trans-unit>改變) 。我與Python和lxml的圖書館...示例工作:獲取相應的XML節點使用XPath

<trans-unit id="tu4" xml:space="preserve"> 
    <seg-source> 
     <mrk mid="0" mtype="seg"> 
      <g id="1">...</g> 
      <g id="2">...</g> 
      <g id="3">...</g> 
      <bx id="7"/>... 
     </mrk> 
     <mrk mid="1" mtype="seg">...</mrk> 
     <mrk mid="2" mtype="seg">... 
      <ex id="7"/> 
      <g id="8"> FROM HERE </g> 
     </mrk> 
    </seg-source> 
    <target xml:lang="en"> 
     <mrk mid="0" mtype="seg"> 
      <g id="1">...</g> 
      <g id="2">...</g> 
      <g id="3">...</g> 
      <bx id="7"/>... 
     </mrk> 
     <mrk mid="1" mtype="seg">...</mrk> 
     <mrk mid="2" mtype="seg">... 
      <ex id="7"/> 
      <g id="8"> TO HERE </g> 
     </mrk> 
    </target> 
</trans-unit> 

正如你所看到的,在2個節點<seg-source><target>具有完全相同的分體結構。我的目標是導航到<seg-source>每個節點,得到的文本和節點的尾部(我知道如何做到這一點使用XPath),翻譯它們最後(這是什麼,我不知道該怎麼辦)分配給<target>中的相應節點翻譯...

換句話說...假設我得到節點「FROM HERE」...我怎樣才能得到節點「TO HERE」?

+0

是否有什麼原因需要手動完成?你看過python中已經存在的XLIFF實現嗎? (例如,[Translate Toolkit]中的'xliff'模塊(https://github.com/translate/translate/tree/master/translate/misc)。 –

回答

0

如果要配對他們所有你能只是壓縮的節點連接在一起,所以你可以從每個訪問匹配代碼:

from lxml import etree 

tree = etree.fromstring(x) 
nodes = iter(tree.xpath("//*[self::seg-source or self::target]")) 
for seq, tar in zip(nodes, nodes): 
    # each node will be the matching nodes from each seq-source and target 
    print(seq.xpath(".//*")) 
    print(tar.xpath(".//*")) 

由於只有中任意兩臺/每trans-unit你可以只使用nodes = iter(tree.xpath("//trans-unit/*"))所以內部節點的名稱並不重要。

nodes = iter(tree.xpath("/trans-unit/*")) 
for seq, tar in zip(nodes, nodes): 
    print(seq.xpath(".//*")) 
    print(tar.xpath(".//*")) 

如果我們運行在您的樣本代碼,並打印每個ID節點,可以看到輸出會分別來自:

In [2]: from lxml import etree 

In [3]: tree = etree.fromstring(x) 

In [4]: nodes = iter(tree.xpath("//trans-unit/*")) 

In [5]: for seq, tar in zip(nodes, nodes): 
    ...:   print(seq.xpath(".//g[@id='8']/text()")) 
    ...:   print(tar.xpath(".//g[@id='8']/text()")) 
    ...:  
[' FROM HERE '] 
[' TO HERE '] 

每個節點是由反式單元的每個孩子對應的節點:

In [7]: for seq, tar in zip(nodes, nodes): 
    ...:   print(seq.tag, tar.tag) 
    ...:   for n1, n2 in zip(seq.xpath(".//*"),tar.xpath(".//*")): 
    ...:     print(n1.tag, n2.tag) 
    ...:   
('seg-source', 'target') 
('mrk', 'mrk') 
('g', 'g') 
('g', 'g') 
('g', 'g') 
('bx', 'bx') 
('mrk', 'mrk') 
('mrk', 'mrk') 
('ex', 'ex') 
('g', 'g') 
+0

謝謝Padraic,但我不認爲我可以實現我需要使用zip ...我想過你的解決方案,但是因爲我不知道每個seg-source和target有什麼樣的孩子,所以我需要循環他們......所以我放棄了配對......儘快我有一個seg-source節點,我用這樣的東西:'爲seg-source.xpath('。'*'')中的aChild'循環所有現有的孩子...然後從每個找到的節點,我需要得到一個指向「目標」節點中相應節點的指針... – Attilio

+0

結構相同,因此每個列表中的每個節點都是相應的節點 –

+0

我編輯了答案以表明它們是相同的。*我需要獲取指向目標節點*中的相應節點,這正是你所擁有的。 –