2014-10-04 83 views
3

我试图在Python中解析XML文档,以便我可以对数据进行操作并写出新文件。那我一起工作的文件全是here,但这里是摘录:使用ElementTree无法获取XML元素

<?xml version="1.0" encoding="UTF-8"?> 
<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult"> 
    <ERRORCODE>0</ERRORCODE> 
    <PRODUCT BUILD="09-11-2013" NAME="FileMaker" VERSION="ProAdvanced 12.0v5"/> 
    <DATABASE DATEFORMAT="M/d/yyyy" LAYOUT="" NAME="All gigs 88-07.fmp12" RECORDS="746" TIMEFORMAT="h:mm:ss a"/> 
    <METADATA> 
     <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="Country" TYPE="TEXT"/> 
     <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="Year" TYPE="TEXT"/> 
     <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="City" TYPE="TEXT"/> 
     <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="State" TYPE="TEXT"/> 
     <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="Theater" TYPE="TEXT"/> 
    </METADATA> 
    <RESULTSET FOUND="746"> 
     <ROW MODID="3" RECORDID="32"> 
      <COL> 
       <DATA/> 
      </COL> 
      <COL> 
       <DATA>1996</DATA> 
      </COL> 
      <COL> 
       <DATA>Pompano Beach</DATA> 
      </COL> 
      <COL> 
       <DATA>FL</DATA> 
      </COL> 
      <COL> 
       <DATA>First Presbyterian Church</DATA> 
      </COL> 
     </ROW> 
     <ROW MODID="3" RECORDID="33"> 
      <COL> 
       <DATA/> 
      </COL> 
      <COL> 
       <DATA>1996</DATA> 
      </COL> 
      <COL> 
       <DATA>Hilton Head</DATA> 
      </COL> 
      <COL> 
       <DATA>SC</DATA> 
      </COL> 
      <COL> 
       <DATA>Self Family Arts Center</DATA> 
      </COL> 
     </ROW> 
     <!-- snip many more ROW elements --> 
    </RESULTSET> 
</FMPXMLRESULT> 

最后,我想用从METADATA字段中的信息来分析在RESULTSET列,但现在我在处理数据时遇到麻烦。这里是我试图让METADATA元素的内容:

import xml.etree.ElementTree as ET 

tree = ET.parse('giglist.xml') 
root = tree.getroot() 
print root 
metadata = tree.find("METADATA") 
print metadata 

此打印出:

<Element '{http://www.filemaker.com/fmpxmlresult}FMPXMLRESULT' at 0x10f982cd0> 
None 

为什么metadata空?我滥用find()方法吗?

+1

你不能 '打印根' 您指定的根之前;错字? – 2014-10-04 19:38:31

+0

@OlofBjarnason错字。 (在帖子中,不在代码中) – 2014-10-04 19:39:59

+0

FWIW,我发现xmltodict比elementtree更方便;它使xml更像json。 – user1277476 2014-10-04 20:28:04

回答

4

您需要处理命名空间。

但是,因为只有给予默认命名空间,你可以找到使用以下语法元素:

import xml.etree.ElementTree as ET 

ns = 'http://www.filemaker.com/fmpxmlresult' 

tree = ET.parse('giglist.xml') 
root = tree.getroot() 

metadata = root.find("{%s}METADATA" % ns) 
print metadata # prints <Element '{http://www.filemaker.com/fmpxmlresult}METADATA' at 0x103ccbe90> 

下面是相关的线程,你可能希望看到:


UPD(得到结果的列表):

import xml.etree.ElementTree as ET 

ns = 'http://www.filemaker.com/fmpxmlresult' 

tree = ET.parse('giglist.xml') 
root = tree.getroot() 

keys = [field.attrib['NAME'] for field in root.findall(".//{%(ns)s}METADATA/{%(ns)s}FIELD" % {'ns': ns})] 
results = [dict(zip(keys, [col.text for col in row.findall(".//{%(ns)s}COL/{%(ns)s}DATA" % {'ns': ns})])) 
      for row in root.findall(".//{%(ns)s}RESULTSET/{%(ns)s}ROW" % {'ns': ns})] 

print results 

打印:

[ 
    {'City': 'Pompano Beach', 'Country': None, 'State': 'FL', 'Theater': 'First Presbyterian Church', 'Year': '1996'}, 
    {'City': 'Hilton Head', 'Country': None, 'State': 'SC', 'Theater': 'Self Family Arts Center', 'Year': '1996'} 
] 
+0

哦,我一直认为命名空间只是XML噪声和混乱。我会试一试;谢谢。 – 2014-10-04 20:01:24

+0

工作就像一个魅力。 – 2014-10-04 20:07:27

+0

这看起来也会返回''开始标记。有什么方法可以避免这种情况,除了在使用结果时将其滤除? – 2014-10-04 20:22:00