我是Python的新手,并且听说它是解析相当大的XML文件(150MB)的最佳方法之一。我无法理解如何遍历标记并仅提取<hw>
和<defunit>
标记,因为它是相当深层嵌套的。
我有一些XML格式如下,我需要使用Python从中提取“hw”和“defunit”标签并将它们转换为.csv格式。
<?xml version="1.0" encoding="UTF-8"?>
<dps-data xmlns="urn:DPS2-metadata" project="SCRABBLELARGE" guid="7d6b7164fde1e064:34368a61:14306b637ab:-8000--4a25ae5c-c104-4c7a-bba5-b434dd4d9314">
<superentry xmlns="urn:COLL" xmlns:d="urn:COLL" xmlns:e="urn:IDMEE" e:id="u583c10bfdbd326ba.31865a51.12110e76de1.-336">
<entry publevel="1" id="a000001" e:id="u583c10bfdbd326ba.31865a51.12110e76de1.-335">
<hwblk>
<hwgrp>
<hwunit>
<hw>aa</hw>
<ulsrc>edsh</ulsrc>
</hwunit>
</hwgrp>
</hwblk>
<datablk>
<gramcat publevel="1" id="a000001.001">
<pospgrp>
<pospunit>
<posp value="noun" />
</pospunit>
</pospgrp>
<sensecat id="a000001.001.01" publevel="1">
<defgrp>
<defunit>
<def>volcanic rock</def>
</defunit>
</defgrp>
</sensecat>
</gramcat>
</datablk>
</entry>
</superentry>
</dps-data>
我希望看到的.csv格式很简单:
hw, defunit
aa, volcanic rock
答案 0 :(得分:1)
lxml
库具有非常强大的XML解析功能,可用于迭代XML树以搜索特定元素。
from lxml import etree
with open(r'path/to/xml', 'r') as xml:
text = xml.read()
tree = lxml.etree.fromstring(text)
row = ['', '']
for item in tree.iter('hw', 'def'):
if item.tag == 'hw':
row[0] = item.text
elif item.tag == 'def':
row[1] = item.text
line = ','.join(row)
with open(r'path/to/csv', 'a') as csv:
csv.write(line + '\n')
如何构建CSV文件主要取决于偏好,但我在上面提供了一个简单的例子。如果有多个<dps-data>
标记,您可以先提取这些元素(可以使用上面显示的相同tree.iter
方法完成),然后将上述逻辑应用于每个元素。
编辑:我应该指出,这个特定的实现将整个XML文件读入内存。如果您一次使用一个150mb的文件,这应该不是问题,但它只是需要注意的事项。
答案 1 :(得分:1)
这个怎么样:
from xml.dom import minidom
xmldoc = minidom.parse('your.xml')
hw_lst = xmldoc.getElementsByTagName('hw')
defu_lst = xmldoc.getElementsByTagName('def')
with open('your.csv', 'a') as out_file:
for i in range(len(hw_lst)):
out_file.write('{0}, {1}\n'.format(hw_lst[i].firstChild.data, defu_lst[i].firstChild.data))
答案 2 :(得分:1)
考虑XSLT,这是一种XML转换语言,可以将源.xml文件操作到各种最终用途结构,包括.csv等文本文件,在method="text"
中指定<xsl:output>
。
Python的lxml模块可以运行XSLT 1.0脚本。下面假定<entry>
标记及其子代用不同的数据重复。并且必须在xsl中处理两个未声明的命名空间。此外,XSLT在较小的XML上往往效率很高,但根据计算机环境而有所不同。
XSLT 脚本(另存为.xsl,将在下面引用)
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:ns1="urn:DPS2-metadata" xmlns="urn:COLL">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/ns1:dps-data/ns1:superentry">
<xsl:text>hw,defunit</xsl:text><xsl:text>
</xsl:text>
<xsl:apply-templates select="ns1:entry"/>
</xsl:template>
<xsl:template match="ns1:entry" namespace="urn:COLL">
<xsl:value-of select="descendant::ns1:hw" namespace="urn:COLL"/><xsl:text>,</xsl:text>
<xsl:value-of select="descendant::ns1:defunit" namespace="urn:COLL"/>
<xsl:text>
</xsl:text>
</xsl:template>
Pyton 脚本
import lxml.etree as ET
// LOAD XML AND XSL SOURCES
xml = ET.parse('Input.xml')
xsl = ET.parse('XSLTScript.xsl')
// TRANSFORM SOURCE
transform = ET.XSLT(xsl)
newdom = transform(xml)
// SAVE AS .CSV
with open('Output.csv'), 'wb') as f:
f.write(newdom)
# hw,defunit
# aa,volcanic rock