用xpath获取对应的XML个节点
Get the corresponding XML nodes with xpath
我有一个 XML 文件(实际上是一个 xliff 文件),其中一个节点有 2 个具有相同子结构的子节点(这是先验未知的,可能非常复杂并且每个 <trans-unit>
).我正在使用 python 和 lxml 库...示例:
<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>
如您所见,<seg-source>
和 <target>
这两个节点具有完全相同的子结构。我的目标是导航到 <seg-source>
的每个节点,获取该节点的文本和尾部(我知道如何使用 xpath 执行此操作),翻译它们,最后(这就是我不知道的) how to do) 分配给<target>
翻译中的相应节点...
换句话说......假设我得到节点"FROM HERE"......我怎样才能得到节点"TO HERE"?。
如果你想将它们全部配对,你只需将节点压缩在一起,这样你就可以从每个节点访问匹配代码:
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(".//*"))
由于 any/each 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 ']
每个节点都是trans-unit的每个child的对应节点:
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')
我有一个 XML 文件(实际上是一个 xliff 文件),其中一个节点有 2 个具有相同子结构的子节点(这是先验未知的,可能非常复杂并且每个 <trans-unit>
).我正在使用 python 和 lxml 库...示例:
<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>
如您所见,<seg-source>
和 <target>
这两个节点具有完全相同的子结构。我的目标是导航到 <seg-source>
的每个节点,获取该节点的文本和尾部(我知道如何使用 xpath 执行此操作),翻译它们,最后(这就是我不知道的) how to do) 分配给<target>
翻译中的相应节点...
换句话说......假设我得到节点"FROM HERE"......我怎样才能得到节点"TO HERE"?。
如果你想将它们全部配对,你只需将节点压缩在一起,这样你就可以从每个节点访问匹配代码:
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(".//*"))
由于 any/each 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 ']
每个节点都是trans-unit的每个child的对应节点:
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')