2012-09-29 14 views
8

次のような構造のXMLファイルがあるとしましょう。XMLをlxmlで解析する - 要素値を抽出する

私は解析する必要
<?xml version="1.0" ?> 
<searchRetrieveResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/zing/srw/ http://www.loc.gov/standards/sru/sru1-1archive/xml-files/srw-types.xsd" xmlns="http://www.loc.gov/zing/srw/"> 
    <records xmlns:ns1="http://www.loc.gov/zing/srw/"> 
    <record> 
     <recordData> 
     <record xmlns=""> 
      <datafield tag="000"> 
      <subfield code="a">123</subfield> 
      <subfield code="b">456</subfield> 
      </datafield> 
      <datafield tag="001"> 
      <subfield code="a">789</subfield> 
      <subfield code="b">987</subfield> 
      </datafield> 
     </record> 
     </recordData> 
    </record> 
    <record> 
     <recordData> 
     <record xmlns=""> 
      <datafield tag="000"> 
      <subfield code="a">123</subfield> 
      <subfield code="b">456</subfield> 
      </datafield> 
      <datafield tag="001"> 
      <subfield code="a">789</subfield> 
      <subfield code="b">987</subfield> 
      </datafield> 
     </record> 
     </recordData> 
    </record> 
    </records> 
</searchRetrieveResponse> 

  • "サブフィールド"(上記の例では例えば123)と
  • 属性値(例えば、000又は001)
の内容

lxmlとXPathを使用してそれを行う方法を知っています。私の最初のコードは以下に貼り付けられています。誰かに私に説明してもらい、値を解析する方法を教えてください。

import urllib, urllib2 
from lxml import etree  

url = "https://dl.dropbox.com/u/540963/short_test.xml" 
fp = urllib2.urlopen(url) 
doc = etree.parse(fp) 
fp.close() 

ns = {'xsi':'http://www.loc.gov/zing/srw/'} 

for record in doc.xpath('//xsi:record', namespaces=ns): 
    print record.xpath("xsi:recordData/record/datafield[@tag='000']", namespaces=ns) 
+0

名前空間 'HTTPの接頭辞' xsi'を使用しているHTTPとXMLを解析することができますが、urllibは必要ありません。また

for df in doc.xpath('//datafield'): print df.attrib for sf in df.getchildren(): print sf.text 

となるだろう:// www.loc.gov/zing/srw/' - これは有効ですが、通常は' xsi'が標準名前空間 'http:// www.w3.org/2001/XMLSchema-instance'のプレフィックスとして使用されます。 – MiMo

答えて

16

を私はあなたのXPathでより直接的次のようになります。この場合datafieldには、あなたが望む要素のためにまっすぐに行きます。

>>> for df in doc.xpath('//datafield'): 
     # Iterate over attributes of datafield 
     for attrib_name in df.attrib: 
       print '@' + attrib_name + '=' + df.attrib[attrib_name] 

     # subfield is a child of datafield, and iterate 
     subfields = df.getchildren() 
     for subfield in subfields: 
       print 'subfield=' + subfield.text 

また、lxmlは名前空間を無視できるように見えます。

+0

はい、私は名前空間が1つしかありません。 – Andrej

6

次の作業コードを試してみてください。

import urllib2 
from lxml import etree 

url = "https://dl.dropbox.com/u/540963/short_test.xml" 
fp = urllib2.urlopen(url) 
doc = etree.parse(fp) 
fp.close() 

for record in doc.xpath('//datafield'): 
    print record.xpath("./@tag")[0] 
    for x in record.xpath("./subfield/text()"): 
     print "\t", x 
+0

POSTはデータのみを表示するように編集され、リストは表示されません。 –

5

私は、あなたが直接

url = "http://dl.dropbox.com/u/540963/short_test.xml" #doesn't work with https though 
doc = etree.parse(url) 
関連する問題