Python 使用beautifulsoup将大型xml文件拆分为多个文件
我正在尝试将大型xml文件拆分为较小的文件,首先我从beautifulsoup开始:Python 使用beautifulsoup将大型xml文件拆分为多个文件,python,xml,beautifulsoup,Python,Xml,Beautifulsoup,我正在尝试将大型xml文件拆分为较小的文件,首先我从beautifulsoup开始: from bs4 import BeautifulSoup import os # Core settings rootdir = r'C:\Users\XX\Documents\Grant Data\2010_xml' extension = ".xml" to_save = r'C:\Users\XX\Documents\all_patents_as_xml' index = 0 for root, di
from bs4 import BeautifulSoup
import os
# Core settings
rootdir = r'C:\Users\XX\Documents\Grant Data\2010_xml'
extension = ".xml"
to_save = r'C:\Users\XX\Documents\all_patents_as_xml'
index = 0
for root, dirs, files in os.walk(rootdir):
for file in files:
if file.endswith(extension):
print(file)
file_name = os.path.join(root,file)
with open(file_name) as f:
data = f.read()
texts = data.split('?xml version="1.0" encoding="UTF-8"?')
for text in texts:
index += 1
filename = to_save + "\\"+ str(index) + ".txt"
with open(filename, 'w') as f:
f.write(text)
但是,我有一个内存错误。然后我切换到xml etree:
from xml.etree import ElementTree as ET
import re
file_name = r'C:\Users\XX\Documents\Grant Data\2010_xml\2010cat_xml.xml'
with open(file_name) as f:
xml = f.read()
tree = ET.fromstring(re.sub(r"(<\?xml[^>]+\?>)", r"\1<root>", xml) + "</root>")
parser = ET.iterparse(tree)
to_save = r'C:\Users\Yilmaz\Documents\all_patents_as_xml'
index = 0
for event, element in parser:
# element is a whole element
if element.tag == '?xml version="1.0" encoding="UTF-8"?':
index += 1
filename = to_save + "\\"+ str(index) + ".txt"
with open(filename, 'w') as f:
f.write(ET.tostring(element))
# do something with this element
# then clean up
element.clear()
我使用Windows操作系统,我知道在Linux你可以把XMLS从Cuffe中分割出来,但是在我的例子中我不知道该怎么办。
< P>如果你的XML因为内存限制而不能加载,你应该考虑使用. 使用SAX,您将读取文档的“小片段”,并对其执行任何操作(例如:将每N个元素保存到一个新文件) Python SAXPython SAX 您的问题和您解决问题的尝试存在重大问题:
xml.etree
的代码非常不正确。在第parser=ET.iterparse(tree)
行中,tree
是一个已经用ET.fromstring
解析过的XML树,但是iterparse
的参数必须是文件名或文件对象。XML树不是这两种树。所以那次尝试在到达时就失败了xml.etree
尝试中,您有以下测试:
element.tag == '?xml version="1.0" encoding="UTF-8"?'
对于这个测试,我可以想象的唯一意图是,您认为xml.etree
会以某种方式将
解释为一个xml元素,其名称为'?xml version=“1.0”encoding=“UTF-8”?
。但是,结构
不是XML元素,而是XML声明
而且,由于您的代码似乎在每次遇到XML声明时都试图进行拆分,您的输入似乎是一个包含多个XML声明的文件。此文件不是有效的XML。XML规范允许XML声明出现一次,并且仅在XML文件的开头出现一次。(不要将XML声明与处理指令混淆。它们看起来很相似,因为它们都由
分隔,但XML声明不是处理指令。)如果在输入文件上使用XML解析器,并且此解析器符合XML规范,然后,它必须拒绝您的文件,因为XML不允许XML声明出现在文档中的任意位置
这会让你怎么办?如果源文档中的所有XML声明都相同,那么有一种相对简单的方法可以通过XML解析器使文档可解析。(您所做的尝试表明它们都是相同的,因为您没有使用正则表达式来匹配不同形式的XML声明(例如,将指定独立的
参数的表达式)。)您只需从源文档中删除所有XML声明,将其包装在新的根元素中,然后用xml.etree
解析它。(这假设连接起来组成源文档的各个XML文档都是单独格式良好的。如果不是这样,那么这将不起作用。)
但是,请注意,字符串
可以出现在XML文档中,而该字符串实际上不是XML声明。下面是一个格式良好的XML文档,它将抛出一个只查找类似XML声明的字符串的算法:
<?xml version = "1.0" encoding = "UTF-8"?>
<a>
<![CDATA[
<?xml version = "1.0" encoding = "UTF-8"?>
]]>
<?q <?xml version = "1.0" encoding = "UTF-8"?> ?>
<!-- <?xml version = "1.0" encoding = "UTF-8"?> -->
</a>
]]>
?>
如果您知道源文件是如何创建的,您可能已经能够确定您没有上述任何情况。否则,您可能需要检查您的源代码,以确保上述情况不会发生
一旦解决了这个问题,那么使用基于
ET.iterparse
,或SAX的策略应该会起作用。xml文件的大小是多少?取决于您提到的使用Beautiful Soup的6 GB左右。然而,当您在代码中导入漂亮的汤时,实际上并没有对它做任何事情我试着用它来分割数据,它用来处理较小的xml文件正如你所说的,我的数据包含多个xml声明,这些是USPTOSo提供的专利文件鉴于beautifulsoup的第一个代码用于较小的文件,我只是在寻找一个内存高效的解决方案
<?xml version = "1.0" encoding = "UTF-8"?>
<a>
<![CDATA[
<?xml version = "1.0" encoding = "UTF-8"?>
]]>
<?q <?xml version = "1.0" encoding = "UTF-8"?> ?>
<!-- <?xml version = "1.0" encoding = "UTF-8"?> -->
</a>