lxml 解析小例子

转载自: http://blog.csdn.net/xia7139/article/details/10195849

运行下列命令,安装成功
apt-get install python2.6-dev
apt-get install libxml2-dev
apt-get install libxslt1-dev
easy_install lxml

另外,安装python idle
apt-get install idle



  1. 例子:dblp.xml(dblp数据的片段)  
  2. xml version='1.0' encoding='utf-8'?>    
  3. <dblp>  
  4.        <article mdate="2012-11-28" key="journals/entropy/BellucciFMY08">    
  5.         <author>Stefano Bellucciauthor>    
  6.         <author>Sergio Ferraraauthor>    
  7.         <author>Alessio Marraniauthor>    
  8.         <author>Armen Yeranyanauthor>    
  9.         <title>ES<sup>2sup>: A cloud data storage system for supporting both OLTP and OLAP.title>  
  10.         <pages>507-555pages>    
  11.         <year>2008year>    
  12.         <volume>10volume>    
  13.         <journal>Entropyjournal>    
  14.         <number>4number>    
  15.         <ee>http://dx.doi.org/10.3390/e10040507ee>    
  16.         <url>db/journals/entropy/entropy10.html#BellucciFMY08url>    
  17.     article>    
  18.     <article mdate="2013-03-04" key="journals/entropy/Knuth13">    
  19.         <author>Kevin H. Knuthauthor>    
  20.         <title><i>Entropyi> Best Paper Award 2013.title>    
  21.         <pages>698-699pages>    
  22.         <year>2013year>    
  23.         <volume>15volume>    
  24.         <journal>Entropyjournal>    
  25.         <number>2number>    
  26.         <ee>http://dx.doi.org/10.3390/e15020698ee>    
  27.         <url>db/journals/entropy/entropy15.html#Knuth13url>    
  28.     article>    
  29. dblp>  
1、将xml解析为树结构,并得到该树的根。

为了将xml解析为树结构,并得到该树的根,要进行如下的操作:

[python]  view plain copy
  1. #!/usr/bin/python  
  2. #-*-coding:utf-8-*-  
  3. from lxml import etree#导入lxml库  
  4. tree = etree.parse("dblp.xml")#将xml解析为树结构  
  5. root = tree.getroot()#获得该树的树根  
另外,如果xml数据中出现了关于dtd的声明(如下面的例子),那样的话,必须在使用lxml解析xml的时候,进行相应的声明。

[html]  view plain copy
  1. xml文件中含有dtd声明的例子:  
  2. xml version="1.0" encoding="ISO-8859-1"?>  
  3. >  
  4. <dblp>  
  5. <article mdate="2002-01-03" key="persons/Codd71a">  
  6. <author>E. F. Coddauthor>  
  7. <title>Further Normalization of the Data Base Relational Model.title>  
  8. <journal>IBM Research Report, San Jose, Californiajournal>  
  9. <volume>RJ909volume>  
  10. <month>Augustmonth>  
  11. <year>1971year>  
  12. hadoop@hadoop:~/20130722dblpxml$ head -15 dblp.xml   
  13. xml version="1.0" encoding="ISO-8859-1"?>  
  14. >  
  15. <dblp>  
  16. <article mdate="2002-01-03" key="persons/Codd71a">  
  17. <author>E. F. Coddauthor>  
  18. <title>Further Normalization of the Data Base Relational Model.title>  
  19. <journal>IBM Research Report, San Jose, Californiajournal>  
  20. <volume>RJ909volume>  
  21. <month>Augustmonth>  
  22. <year>1971year>  
  23. <cdrom>ibmTR/rj909.pdfcdrom>  
  24. <ee>db/labs/ibm/RJ909.htmlee>  
  25. article>  
  26. dblp>  

这时候,要想将xml数据解析为树结构并得到该树的树根,必须进行如下的操作:

[python]  view plain copy
  1. #!/usr/bin/python  
  2. #-*-coding:utf-8-*-  
  3. from lxml import etree#导入lxml库  
  4. parser=etree.XMLParser(load_dtd= True)#首先根据dtd得到一个parser(注意dtd文件要放在和xml文件相同的目录)  
  5. tree = etree.parse("dblp.xml",parser)#用上面得到的parser将xml解析为树结构  
  6. root = tree.getroot()#获得该树的树根  
2、遍历树结构,获得各元素的属性及其子元素。

[python]  view plain copy
  1. for article in root:#这样便可以遍历根元素的所有子元素(这里是article元素)  
  2.     print "元素名称:",article.tag#用.tag得到该子元素的名称  
  3.     for field in article:#遍历article元素的所有子元素(这里是指article的author,title,volume,year等)  
  4.         print field.tag,":",field.text#同样地,用.tag可以得到元素的名称,而.text可以得到元素的内容  
  5.     mdate=article.get("mdate")#用.get("属性名")可以得到article元素相应属性的值  
  6.     key=article.get("key")  
  7.     print "mdate:",mdate  
  8.     print "key",key  
  9.     print ""#隔行分开不同的article元素  
到这里,便可以进行简单的xml数据的解析了。

3、解析xml数据的例子

用下面的代码解析文章开头的名为dblp.xml数据。

[python]  view plain copy
  1. #!/usr/bin/python  
  2. #-*-coding:utf-8-*-  
  3. from lxml import etree#导入lxml库  
  4. tree = etree.parse("dblp.xml")#将xml解析为树结构  
  5. root = tree.getroot()#获得该树的树根  
  6.   
  7. for article in root:#这样便可以遍历根元素的所有子元素(这里是article元素)  
  8.     print "元素名称:",article.tag#用.tag得到该子元素的名称  
  9.     for field in article:#遍历article元素的所有子元素(这里是指article的author,title,volume,year等)  
  10.         print field.tag,":",field.text#同样地,用.tag可以得到元素的名称,而.text可以得到元素的内容  
  11.     mdate=article.get("mdate")#用.get("属性名")可以得到article元素相应属性的值  
  12.     key=article.get("key")  
  13.     print "mdate:",mdate  
  14.     print "key",key  
  15.     print ""#隔行分开不同的article元素  
便可以得到输出如下:

[python]  view plain copy
  1. 元素名称: article  
  2. author : Stefano Bellucci  
  3. author : Sergio Ferrara  
  4. author : Alessio Marrani  
  5. author : Armen Yeranyan  
  6. title : ES  
  7. pages : 507-555  
  8. year : 2008  
  9. volume : 10  
  10. journal : Entropy  
  11. number : 4  
  12. ee : http://dx.doi.org/10.3390/e10040507  
  13. url : db/journals/entropy/entropy10.html#BellucciFMY08  
  14. mdate: 2012-11-28  
  15. key: journals/entropy/BellucciFMY08  
  16.   
  17.   
  18. 元素名称: article  
  19. author : Kevin H. Knuth  
  20. title : None  
  21. pages : 698-699  
  22. year : 2013  
  23. volume : 15  
  24. journal : Entropy  
  25. number : 2  
  26. ee : http://dx.doi.org/10.3390/e15020698  
  27. url : db/journals/entropy/entropy15.html#Knuth13  
  28. mdate: 2013-03-04  
  29. key: journals/entropy/Knuth13  

4、元素既有sub-element,又有text的处理

可以看到在上面的例子中,title元素的内容是不正确的。由于title元素及包含sub-element,又有text内容(如下),这时简单的用.text,并不能正确的得到title元素的内容。上面的例子中,第一个article元素的title只取到了ES,而第二个article元素的title则什么都没取到,None。

[python]  view plain copy
  1. ES<sup></span><span class="number" style="margin:0px; padding:0px; border:none; background-color:inherit">2</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"></sup>: A cloud data storage system </span><span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); background-color:inherit; font-weight:bold">for</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> supporting both OLTP </span><span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); background-color:inherit; font-weight:bold">and</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> OLAP.  
  2. <i>Entropy</i> Best Paper Award <span class="number" style="margin:0px; padding:0px; border:none; background-color:inherit">2013.</span><span style="margin:0px; padding:0px; border:none; background-color:inherit">   
由于在这个例子中,子元素比较简单,这里就简单的采取将子元素和text一起打印的方法来解决这一问题。代码如下:

[python]  view plain copy
  1. #!/usr/bin/python  
  2. #-*-coding:utf-8-*-  
  3. from lxml import etree#导入lxml库  
  4. tree = etree.parse("dblp.xml")#将xml解析为树结构  
  5. root = tree.getroot()#获得该树的树根  
  6.   
  7. for article in root:#这样便可以遍历根元素的所有子元素(这里是article元素)  
  8.     print "元素名称:",article.tag#用.tag得到该子元素的名称  
  9.     for field in article:#遍历article元素的所有子元素(这里是指article的author,title,volume,year等)  
  10.         if field.tag=="title":  
  11.             print field.tag,":",etree.tostring(field,encoding='utf-8',pretty_print=False)#将元素text连同sub_element一起打印  
  12.         else:  
  13.             print field.tag,":",field.text#同样地,用.tag可以得到元素的名称,而.text可以得到元素的内容  
  14.     mdate=article.get("mdate")#用.get("属性名")可以得到article元素相应属性的值  
  15.     key=article.get("key")  
  16.     print "mdate:",mdate  
  17.     print "key:",key  
  18.     print ""#隔行分开不同的article元素  
输出如下:

[python]  view plain copy
  1. 元素名称: article  
  2. author : Stefano Bellucci  
  3. author : Sergio Ferrara  
  4. author : Alessio Marrani  
  5. author : Armen Yeranyan  
  6. title : ES<sup><span class="number" style="margin:0px; padding:0px; border:none; background-color:inherit">2</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"></sup>: A cloud data storage system </span><span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); background-color:inherit; font-weight:bold">for</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> supporting both OLTP </span><span class="keyword" style="margin:0px; padding:0px; border:none; color:rgb(0,102,153); background-color:inherit; font-weight:bold">and</span><span style="margin:0px; padding:0px; border:none; background-color:inherit"> OLAP.  
  7.           
  8. pages : 507-555  
  9. year : 2008  
  10. volume : 10  
  11. journal : Entropy  
  12. number : 4  
  13. ee : http://dx.doi.org/10.3390/e10040507  
  14. url : db/journals/entropy/entropy10.html#BellucciFMY08  
  15. mdate: 2012-11-28  
  16. key: journals/entropy/BellucciFMY08  
  17.   
  18. 元素名称: article  
  19. author : Kevin H. Knuth  
  20. title : <i>Entropy</i> Best Paper Award <span class="number" style="margin:0px; padding:0px; border:none; background-color:inherit">2013.</span><span style="margin:0px; padding:0px; border:none; background-color:inherit">    
  21.           
  22. pages : 698-699  
  23. year : 2013  
  24. volume : 15  
  25. journal : Entropy  
  26. number : 2  
  27. ee : http://dx.doi.org/10.3390/e15020698  
  28. url : db/journals/entropy/entropy15.html#Knuth13  
  29. mdate: 2013-03-04  
  30. key: journals/entropy/Knuth13  
当然,不难看出这个问题用这种方法解决比较傻,后面还得将title内容中的tag等不需要部分通过各种字符串的处理将其去掉。最好的方法是能有比较简单的方法,分别获取到一个元素的text和sub_element。有比较好的解决办法,欢迎指教。

你可能感兴趣的:(脚本语言-python)