我正在尝试将用户列表从Jaspersoft服务器导出为CSV格式,因为我们目前无权访问数据库或任何管理面板,我们必须提出支持服务单,每次我们等待2天想要一份清单。我想我会尝试使用REST API和python,并在请求模块的帮助下,我设法导出保存此信息的XML。提取的XML的格式是这样的。
示例XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<users>
<user>
<emailAddress>doejoe@email.com</emailAddress>
<enabled>true</enabled>
<fullName>John Doe</fullName>
<username>doejoe</username>
<roles>
<role>
<externallyDefined>false</externallyDefined>
<name>MANAGER</name>
<desc>Beatings will continue until morale improves</desc>
</role>
<role>
<externallyDefined>false</externallyDefined>
<name>DIRECTOR</name>
</role>
</roles>
</user>
<user>
<emailAddress>kathysmith@email.com</emailAddress>
<enabled>true</enabled>
<fullName>Kathy Smith</fullName>
<username>kathysmith</username>
<externallyDefined>false</externallyDefined>
<roles>
<role>
<externallyDefined>false</externallyDefined>
<name>USER</name>
<desc>User Description</desc>
</role>
<role>
<externallyDefined>false</externallyDefined>
<name>SUPER_MANAGER</name>
<desc>Super Manager description.</desc>
</role>
<role>
<externallyDefined>false</externallyDefined>
<name>SUPER_DIRECTOR</name>
</role>
</roles>
</user>
</users>
我的代码到现在为止:
import lxml.etree as ET
import csv
# load file
tree = ET.parse('Format.xml')
# iterate through each user tag
users = tree.findall('.//user')
with open('user_list.csv', "wb") as csv_file:
writer = csv.writer(csv_file, delimiter=',')
for user in users:
email = user.find('emailAddress').text
enabled = user.find('enabled').text
externallyDefined = user.find('externallyDefined').text
fullName = user.find('fullName').text
tenantId = user.find('tenantId').text
username = user.find('username').text
writer.writerow(email + ',' + enabled + ',' + externallyDefined + ',' + fullName + ',' + tenantId + ',' + username)
正如你所知道的那样 - 我不是一个程序员,甚至不是那么接近,所以你的眼睛应该道歉 - 3周前开始学习python。我的代码无法正常工作:
我的最终目标是这样的:
我将非常感谢任何帮助/方向,我将如何解决这些问题,因为我现在完全迷失了。周末愉快!
答案 0 :(得分:0)
尝试这样的事情:
import lxml.etree as ET
import csv
# load file
tree = ET.parse('users.xml')
# iterate through each user tag
users = tree.findall('.//user')
# just w mode, no wb. wb is for binary data
with open('user_list.csv', "w") as csv_file:
writer = csv.writer(csv_file, delimiter=',')
# write headers
writer.writerow([
'email', 'enabled', 'externallyDefined',
'fullName', 'tenantId', 'username', 'director',
'manager', 'user', 'super manager', 'super director'
])
for user in users:
email = user.find('emailAddress').text
enabled = user.find('enabled').text
# process optional element
externallyDefined = user.find('externallyDefined')
if externallyDefined is not None:
externallyDefined = externallyDefined.text
fullName = user.find('fullName').text
# another optional element
tenantId = user.find('tenantId')
if tenantId is not None:
tenantId = tenantId.text
username = user.find('username').text
# collect nested elements (roles)
user_roles = {}
roles = user.find('roles').findall('role')
for role in roles:
user_roles[role.find('name').text] = True
writer.writerow([
email, enabled, externallyDefined, fullName,
tenantId, username, user_roles.get('DIRECTOR'),
user_roles.get('MANAGER'), user_roles.get('USER'),
user_roles.get('SUPER_MANAGER'), user_roles.get('SUPER_DIRECTOR')
])
答案 1 :(得分:0)
一般方法很简单。
...我们可以概括为:
为此,我们基本上需要
extract_val()
,它接受一个XML节点,对它运行XPath,并返回第一个找到的值。.xpath()
方法can return都是简单值(字符串,布尔值,浮点数)和节点或值列表。xml_extract()
,可以获取XML文档,迭代对象并将extract_val()
应用于每个文档,返回值列表csv.writerows()
一次性写出来。在代码中:
import lxml.etree as ET
def extract_val(context_node, xpath):
'''Extracts one value from an XML node'''
result = context_node.xpath(xpath)
if isinstance(result, list):
result = result[0] if len(result) > 0 else None
if isinstance(result, ET._Element):
return result.text
if isinstance(result, (bool, float, str)):
return result
def xml_extract(tree_or_path, object_xpath, property_xpaths):
'''Extracts lists of values from an XML tree (or path to an XML file)'''
if isinstance(tree_or_path, ET._ElementTree):
tree = tree_or_path
if isinstance(tree_or_path, str):
tree = ET.parse(tree_or_path)
for elem in tree.xpath(object_xpath):
yield [extract_val(elem, path) for path in property_xpaths]
#----------------------------------------------------------------------
import csv
with open('user_list.csv', 'w', encoding='utf8', newline='') as csv_file:
writer = csv.writer(csv_file, delimiter=',')
rows = xml_extract('Format.xml', '//user', [
'emailAddress',
'enabled',
'externallyDefined',
'fullName',
'tenantId',
'username',
'count(roles/role[name = "DIRECTOR"]) > 0',
'count(roles/role[name = "MANAGER"]) > 0',
])
writer.writerows(rows)
这种方法非常灵活,可以从任何XML中提取值表,您可能需要turn it into a module,以便重复使用。