尝试使用 lxml 删除空 xml 标签时出现解析错误
Getting parsing error when attempting to remove empty xml tags with lxml
我正在从 csv 源创建一个 xml 文件,在此过程中,用户提供了一些非常有用的输入。看来我的最后一个要求(我才刚刚意识到)是在调用 API.[=14 之前删除任何空的 xml 标签(即没有内容的标签) =]
我正在尝试使用 etree remove 方法删除空标签,但出现 etree.fromstring 只能解析字符串的错误。这是我的示例数据和代码。
ACTION|INV_ACCT_CLASS|EXT_INV_ID|WAREHOUSE_ID|NAME|CNTRY_CD|PHONE|ADDR_STR1|ADDR_STR2|CITY|ST|ZIP|ADD_KEY_NUM
add|2|AAA_00005|1001213|Company 1|US|9995555555|1313 Mockingbird Lane||New York|NY|10001|44433322
add|2|BBB_00008|1004312|Company 2|US|43255511110|Some other address||Stamford|CT|44112|11122233
import lxml.etree
from lxml.builder import E
import csv
import string
import date from datetime
with open("filename.csv") as csvfile:
results = E.paiInv(*(
E.invrec(
E.action(row['ACTION']),
E.investor(
E.inv_account_class(row['INV_ACCOUNT_CLASS']),
E.ext_inv_id(row['EXT_INV_ID']),
E.warehouse_id(row['WAREHOUSE_ID']),
E.name(row['NAME']),
E.cntry_cd(row['CNTRY_CD']),
E.phone(row['PHONE']),
E.addr_str1(row['ADDRESS_STR1']),
E.addr_str2(row['ADDRESS_STR2']),
E.city(row['CITY']),
E.st(row['ST']),
E.zip(row['ZIP']),
E.add_key_num(row['ADD_KEY_NUM'])
)
) for row in csv.DictReader(csvfile, delimiter = '|'))
)
req = '<request_id>Investor' + str(date.today()) + '</request_id>'
doc = lxml.etree.ElementTree(results)
ins = lxml.etree.fromstring(req)
ins.tail = "\n"
dest = doc.xpath('/paiInv')[0]
dest.insert(0,ins)
这正是我所需要的,除了如果 csv 中的任何列为空,我将得到空的 xml 标签,正如预期的那样。由于我们需要删除任何空标签,因此我尝试了以下代码:
root = lxml.etree.fromstring(results)
for element in root.xpath(".//*[not(node())]"):
element.getparent().remove(element)
我收到一条错误消息“只能解析字符串”。我试图理解为什么它会找到字符串以外的任何东西,以及我应该如何调整代码以正确地删除空标签。
谢谢!
这是一种处理方法:将最后的 for
循环更改为:
for element in root.xpath('//*'):
if element.text is None:
elememt.getparent().remove(element)
输出现在应该删除了两个 <addr_str2>
个空节点。
我正在从 csv 源创建一个 xml 文件,在此过程中,用户提供了一些非常有用的输入。看来我的最后一个要求(我才刚刚意识到)是在调用 API.[=14 之前删除任何空的 xml 标签(即没有内容的标签) =]
我正在尝试使用 etree remove 方法删除空标签,但出现 etree.fromstring 只能解析字符串的错误。这是我的示例数据和代码。
ACTION|INV_ACCT_CLASS|EXT_INV_ID|WAREHOUSE_ID|NAME|CNTRY_CD|PHONE|ADDR_STR1|ADDR_STR2|CITY|ST|ZIP|ADD_KEY_NUM
add|2|AAA_00005|1001213|Company 1|US|9995555555|1313 Mockingbird Lane||New York|NY|10001|44433322
add|2|BBB_00008|1004312|Company 2|US|43255511110|Some other address||Stamford|CT|44112|11122233
import lxml.etree
from lxml.builder import E
import csv
import string
import date from datetime
with open("filename.csv") as csvfile:
results = E.paiInv(*(
E.invrec(
E.action(row['ACTION']),
E.investor(
E.inv_account_class(row['INV_ACCOUNT_CLASS']),
E.ext_inv_id(row['EXT_INV_ID']),
E.warehouse_id(row['WAREHOUSE_ID']),
E.name(row['NAME']),
E.cntry_cd(row['CNTRY_CD']),
E.phone(row['PHONE']),
E.addr_str1(row['ADDRESS_STR1']),
E.addr_str2(row['ADDRESS_STR2']),
E.city(row['CITY']),
E.st(row['ST']),
E.zip(row['ZIP']),
E.add_key_num(row['ADD_KEY_NUM'])
)
) for row in csv.DictReader(csvfile, delimiter = '|'))
)
req = '<request_id>Investor' + str(date.today()) + '</request_id>'
doc = lxml.etree.ElementTree(results)
ins = lxml.etree.fromstring(req)
ins.tail = "\n"
dest = doc.xpath('/paiInv')[0]
dest.insert(0,ins)
这正是我所需要的,除了如果 csv 中的任何列为空,我将得到空的 xml 标签,正如预期的那样。由于我们需要删除任何空标签,因此我尝试了以下代码:
root = lxml.etree.fromstring(results)
for element in root.xpath(".//*[not(node())]"):
element.getparent().remove(element)
我收到一条错误消息“只能解析字符串”。我试图理解为什么它会找到字符串以外的任何东西,以及我应该如何调整代码以正确地删除空标签。
谢谢!
这是一种处理方法:将最后的 for
循环更改为:
for element in root.xpath('//*'):
if element.text is None:
elememt.getparent().remove(element)
输出现在应该删除了两个 <addr_str2>
个空节点。