2016-04-03 132 views
0

我有一个具有数据列表的长XML文件列表。基于“ID”,我想从文件中删除一些节点。如果ID值重复且没有元数据,那么我想保留具有元数据的文件节点并删除其他元数据。 如果相同的ID值看到两次,都没有元数据,然后保留第一个和删除第二个。根据条件删除XML文件中的重复条目。

Input.xml中

<?xml version="1.0"?> 
<Def check=""> 
-<ID Elm="Front Sonar" ID="Opt-0001"/> 

-<ID Elm="Rear Sonar" ID="Opt-0002"> 
<BlockID Wid="100" Auto="true"/> 
<Check Auto="true" Siz="20" Nam="Fonts"/> 
<Update Auto="true" Nam="Styles"/> 
-<Updates Auto="true"> 
<Update Name="Type_1"/> 
<Update Name="Type_21"/> 
</Updates> 
</ID> 
-<ID Elm="Sonar Settings" ID="Opt-0003"> 
<BlockID Wid="80" Auto="true"/> 
<Check Auto="true" Siz="2" Nam="Fun"/> 
<Update Auto="true" Nam="done"/> 
-<Updates Auto="true"> 
<Update Name="Type_31"/> 
<Update Name="Type_2"/> 
</Updates> 
</ID> 
-<ID Elm="Sonar" ID="Opt-0004"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="Menu" ID="ValOpt-0001"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="Cancel" ID="ValOpt-0002"/> 
-<ID Elm="Go Home" ID="ValOpt-0003"/> 
-<ID Elm="Group" ID="Opt-0001"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="School" ID="Opt-0002"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="Book" ID="Opt-0003"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="Lang" ID="ValOpt-0001"> 
<BlockID Wid="100" Auto="true"/> 
<Check Auto="true" Siz="20" Nam="Fonts"/> 
<Update Auto="true" Nam="Styles"/> 
-<Updates Auto="true"> 
<Update Name="Type_1"/> 
<Update Name="Type_21"/> 
</Updates> 
</ID> 
-<ID Elm="Back" ID="ValOpt-0002"> 
<BlockID Wid="80" Auto="true"/> 
<Check Auto="true" Siz="2" Nam="Fun"/> 
<Update Auto="true" Nam="done"/> 
-<Updates Auto="true"> 
<Update Name="Type_31"/> 
<Update Name="Type_2"/> 
</Updates> 
</ID> 
-<ID Elm="Exit" ID="ValOpt-0003"/> 
</Def> 

预期的Output.xml

<?xml version="1.0"?> 
<Def check=""> 
-<ID Elm="Front Sonar" ID="Opt-0001"/> 
-<ID Elm="Rear Sonar" ID="Opt-0002"> 
<BlockID Wid="100" Auto="true"/> 
<Check Auto="true" Siz="20" Nam="Fonts"/> 
<Update Auto="true" Nam="Styles"/> 
-<Updates Auto="true"> 
<Update Name="Type_1"/> 
<Update Name="Type_21"/> 
</Updates> 
</ID> 
-<ID Elm="Sonar Settings" ID="Opt-0003"> 
<BlockID Wid="80" Auto="true"/> 
<Check Auto="true" Siz="2" Nam="Fun"/> 
<Update Auto="true" Nam="done"/> 
-<Updates Auto="true"> 
<Update Name="Type_31"/> 
<Update Name="Type_2"/> 
</Updates> 
</ID> 
-<ID Elm="Sonar" ID="Opt-0004"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="Cancel" ID="ValOpt-0002"/> 
-<ID Elm="Go Home" ID="ValOpt-0003"/> 
-<ID Elm="Group" ID="Opt-0001"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="Lang" ID="ValOpt-0001"> 
<BlockID Wid="100" Auto="true"/> 
<Check Auto="true" Siz="20" Nam="Fonts"/> 
<Update Auto="true" Nam="Styles"/> 
-<Updates Auto="true"> 
<Update Name="Type_1"/> 
<Update Name="Type_21"/> 
</Updates> 
</ID> 
-<ID Elm="Back" ID="ValOpt-0002"> 
<BlockID Wid="80" Auto="true"/> 
<Check Auto="true" Siz="2" Nam="Fun"/> 
<Update Auto="true" Nam="done"/> 
-<Updates Auto="true"> 
<Update Name="Type_31"/> 
<Update Name="Type_2"/> 
</Updates> 
</ID> 
</Def> 

使用Element树,我试图检查 如果从列表行starteswith “” #remove elemet。 else 打印“元素有元数据”
但不幸的是我的函数没有进入循环本身....我总是在其他条件下获得print语句。任何帮助有关这?

回答

0

期望的输出仍然有一些重复。从下面的代码的输出与预期不同,但它实际上删除所有重复:

from lxml import etree 

xml_input = 'Input.xml' 
xml_output = 'Output.xml' 

with open(xml_input) as xml: 
    root = etree.XML(xml.read()) 

#create dictionary where key is an ID and value is a list of nodes with the ID 
node_dict = {} 
for node in root.xpath('//*[@ID]'): 
    try: 
     node_dict[node.get('ID')].append(node) 
    except KeyError: 
     node_dict[node.get('ID')] = [node] 

for key, nodes in node_dict.iteritems(): 
    #find all nodes with childs 
    nodes_with_childs = [node for node in nodes if len(node.xpath('./*')) > 0] 

    #leave only first node with childs, remove other nodes 
    if len(nodes_with_childs) > 0: 
     for node in set(nodes) - set([nodes_with_childs[0]]): 
     node.getparent().remove(node) 
    else: 
     #leave only first node, remove other nodes 
     for node in nodes[1:]: 
     node.getparent().remove(node) 

with open(xml_output, 'w') as xml: 
    xml.write(etree.tostring(root, xml_declaration=True)) 
+0

它完美罚款...感谢ü... – HARPAL

+0

找到1个问题......在节点的一些文本的特殊字符。 ..应对XML文件可以看到一些特殊字符的垃圾值...这怎么处理? – HARPAL

+0

我在我的Input.xml文件中有这样的一行 “” 删除重复条目并将内容复制到output.xml ,其数值变为 HARPAL