使用LXML写入XML文件时遇TypeError问题求助
解决LXML生成XML时的TypeError问题&创建带DTD的规范XML
嘿,这个问题我太熟了!LXML的etree.tostring()默认返回的是字节流(bytes类型),而不是你预期的字符串,如果你用文本模式('w')写入文件,自然会触发TypeError: must be str, not bytes。咱们一步步解决,顺便把你要的DTD规范也加上,完全贴合你的需求~
一、先搞定bytes转字符串的核心问题
有两种简单的解决方式,选哪种看你的写入习惯:
方式1:转成字符串后用文本模式写入
给etree.tostring()指定encoding='utf-8'参数,再调用.decode('utf-8')把字节流转成字符串,就能直接用文本模式写入了:
from lxml import etree # 先创建你的XML结构 root = etree.Element("root") child = etree.SubElement(root, "child") child.text = "Hello World" # 转成字符串(关键:指定encoding+decode) xml_str = etree.tostring(root, encoding='utf-8', xml_declaration=True, pretty_print=True).decode('utf-8') # 文本模式写入文件 with open("output.xml", "w", encoding='utf-8') as f: f.write(xml_str)
方式2:直接用二进制模式写入文件
如果不想转字符串,直接用二进制模式('wb')写入,跳过decode步骤:
from lxml import etree root = etree.Element("root") child = etree.SubElement(root, "child") child.text = "Hello World" # 直接获取bytes,二进制写入 xml_bytes = etree.tostring(root, encoding='utf-8', xml_declaration=True, pretty_print=True) with open("output.xml", "wb") as f: f.write(xml_bytes)
小贴士:加上
pretty_print=True会让XML格式更美观,符合规范;xml_declaration=True会自动加上XML声明(<?xml version='1.0' encoding='UTF-8'?>),这也是规范XML的必备项。
二、添加DTD规范
接下来给你的XML加上DTD,LXML支持两种方式关联DTD:
方式1:内嵌DOCTYPE声明
直接在创建根节点时指定DOCTYPE,或者手动拼接进XML内容里:
from lxml import etree # 定义DTD内容 dtd_content = """<!DOCTYPE root [ <!ELEMENT root (child)> <!ELEMENT child (#PCDATA)> ]>""" # 创建XML结构 root = etree.Element("root") child = etree.SubElement(root, "child") child.text = "Hello World" # 先转成字符串,再把DTD拼在最前面 xml_str = etree.tostring(root, encoding='utf-8', pretty_print=True).decode('utf-8') full_xml = dtd_content + "\n" + xml_str # 写入文件 with open("output_with_dtd.xml", "w", encoding='utf-8') as f: f.write(full_xml)
方式2:用LXML的DTD对象关联(更严谨)
如果需要验证XML和DTD的合法性,可以创建etree.DTD对象,然后验证你的XML树:
from lxml import etree # 从字符串加载DTD dtd = etree.DTD("""<!DOCTYPE root [ <!ELEMENT root (child)> <!ELEMENT child (#PCDATA)> ]>""") # 创建XML树 root = etree.Element("root") child = etree.SubElement(root, "child") child.text = "Hello World" # 验证XML是否符合DTD规范 if dtd.validate(root): print("XML符合DTD规范!") # 生成带DOCTYPE的XML内容 xml_str_with_dtd = etree.tostring(root, encoding='utf-8', xml_declaration=True, pretty_print=True, doctype=dtd_content).decode('utf-8') with open("validated_xml.xml", "w", encoding='utf-8') as f: f.write(xml_str_with_dtd) else: print("XML不符合DTD规范:", dtd.error_log)
这样生成的XML不仅格式规范,还包含了DTD声明,完全满足你的需求~
内容的提问来源于stack exchange,提问作者artomason
相关产品推荐
相关产品推荐

