我有一个名为vs_origonal_M.xml的主xml文件我想添加某个孩子的所有类型
<location>
</location>
<location>
</location>
.
.
.
<location>
</location>
直到查看完所有文件。
我这样做是先打开目录,然后我正在制作目录中所有文件的列表,并检查它们是否确实是xml文件,然后我将某个孩子带出去。然后(这里是我被困的地方)我需要打开主文件并将这个孩子插入到同名的最后一个子项下,最后当我完成所有我需要保存主xml文件
以下是代码:
# List the xml files in the directory
from xml.dom import minidom
from xml.etree import ElementTree as ET
import glob
import os
import sys
def is_xml(HART_filename):
string_length = len(HART_filename)
suffix = '.xml'
if HART_filename.endswith(suffix):
return True
else:
return False
#add the directory to the python script
os.chdir("c:/Users/ME/Documents/XML_Parasing_Python")
#List all the files in an array
xml_list = os.listdir("c:/Users/ME/Documents/XML_Parasing_Python")
print xml_list
xml_list_length = len(xml_list)
print xml_list_length
number = 1
for number in range(1,xml_list_length):
string_length = len(xml_list[number])
#print string_length
print xml_list[number]
#check to see if file is .xml
if is_xml(xml_list[number]) == True:
xmldoc = minidom.parse(xml_list[number])
reflist = xmldoc.getElementsByTagName('location')
var_ref = reflist[0]
print reflist[0].toxml()
#Add to master .xml file
tree = ET.parse('vs_original_M.xml')
number += 1
else:
number += 1
print 'wasn''t true'
答案 0 :(得分:1)
可能有更好的方法来做你真正想做的事情 - 特别是,真正的XML很可能只有一个<locations>
标签,所有<location>
标签都在下面,所以有没理由完全搜索最后一个<location>
标签...
但这是你怎么做的。
os.chdir('c:/Users/ME/Documents/XML_Parasing_Python/')
origname = 'vs_original_M.xml'
master = ET.parse(origname)
for path in os.listdir('.'):
if path != origname and os.path.splitext(path)[-1] == '.xml':
child = ET.parse(path)
root = child.getroot()
last_location_parent = master.find('.//*[{}][last()]'.format(root.tag))
last_location_parent.append(root)
master.write('master.xml')
大部分内容非常简单。您必须找到最后一个location
节点的父节点,然后您可以append
另一个节点。
唯一棘手的问题是find
中的XPath表达式,所以让我为你分解它(但你必须阅读文档才能真正理解它!):
.//
表示“当前节点的后代”。 (从技术上讲,你应该只能使用//
作为“root的后代”,但是早期版本的etree中存在错误,所以这样更安全。)*
表示“带有任何标记名称”。[location]
表示“带有孩子”位置“标记。(当然我正在使用format
方法填写孩子的根标签。如果您知道所有孩子都有{{ 1}}作为根,您可以对标记名称进行硬编码,并将location
移出循环。)find
表示“最后一个”。所以,把它们放在一起,这是根的最后一个后代,任何带有子“location”标记的名称。
如果您不了解XPath,您可以随时手动迭代以获得相同的效果,但它会更长,更容易引入细微的错误,因此非常值得学习XPath。
我在你的程序中改变了很多其他的东西。让我解释一下:
没有理由[last()]
if foo: return True
;你可以做else: return False
。但这意味着你的整个函数只是return foo
,所以你甚至不需要一个函数。最好使用路径函数,如return HART_filename.endswith('.xml')
,而不是路径上的字符串函数。
如果您执行os.path.splitext
,则开始时不需要for number in range(1, xml_list_length)
,循环中不需要number = 1
; number += 1
语句已经为您做了。
但是你不想从1开始; Python列表从0开始编制索引。如果您使用它来跳过for
,那只有在您运气好的情况下才有效; vs_original_M.xml
返回内容的顺序是未指定且任意的。跳过具有特定名称的文件的唯一方法是检查其名称。
你几乎不想循环listdir
。如果您只需要range(len(foo))
的元素,请执行foo
。如果您还需要每个元素的索引,请执行for element in foo
。
最后,你几乎不应该检查for index, element in enumerate(foo)
。在Python中,除了if foo == True
(数字True
,字符串“hello”等)之外,很多东西都是“真实的”,你可以使用74
检查foo是否是truthy。如果您明确要确保其失败或其他真实值,请仅使用if foo
;如果您只想检查布局函数的结果,如== True
或is_xml
或endswith
运算符,请直接检查。