2016-03-31 7 views
2

Ich kann nicht verstehen, warum ich einen Fehler erhalte, während ich versuche, den Zeitstempel zu erreichen. XML-Format (einige Attribute wurden weggelassen):Der Elementbaum xml

BEARBEITEN: Dies ist der tatsächliche Typ der XML-Datei.

<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en"> 
    <siteinfo> 
     <sitename>Wikipedia</sitename> 
     <dbname>enwiki</dbname> 
     <base>https://en.wikipedia.org/wiki/Main_Page</base> 
     <generator>MediaWiki 1.27.0-wmf.18</generator> 
     <case>first-letter</case> 
     <namespaces>...</namespaces> 
    </siteinfo> 
    <page> 
     <title>Zhuangzi</title> 
     <ns>0</ns> 
     <id>42870472</id> 
     <revision> 
      <id>610251969</id> 
      <timestamp>2014-05-26T20:08:14Z</timestamp> 
      <contributor> 
       <username>White whirlwind</username> 
       <id>8761551</id> 
      </contributor> 
      <comment>...</comment> 
      <model>wikitext</model> 
      <format>text/x-wiki</format> 
      <text xml:space="preserve" bytes="41">#REDIRECT [[Zhuang Zhou]] {{R from move}}</text> 
      <sha1>9l31fcd4fp0cfxgearifr7jrs3240xl</sha1> 
     </revision> 
     <revision>...</revision> 
     <revision>...</revision> 
     <revision>...</revision> 
     <revision>...</revision> 
     <revision>...</revision> 

    </page> 
    <page>...</page> 
</mediawiki> 

Aber wenn ich versuche, die folgenden:

for page in root:   
    for revision in page: 
    print(revision.find('timestamp').text) 

Ich erhalte die Fehler

print(revision.find('timestamp').text) 
    AttributeError: 'NoneType' object has no attribute 'text' 
+0

Sie sagen, Sie für '‚Zeitstempel‘suchen 'in einem 'revision'-Objekt:' revision.find (' timestamp ') ', aber die Fehlermeldung besagt, dass Sie in' revision '' revision' gesucht haben: 'revision.find (' revision ')'. Welches ist wahr? – CiaPan

+0

'timestamp' ist derjenige, den ich suche – Knokkelgeddon

Antwort

1

Sie sind so offensichtlich über jeden Tag Iterieren mit .find auf jedem Tag wird sich zurück Keine, daher Ihr Fehler:

In [9]: for page in root: 
      print(page.tag) 
      for revision in page: 
        print(revision.tag) 
    ...:   

id 
timestamp 
contributor 
comment 
model 

Ihre eigene Methode verwenden Sie müssten jeden Tag überprüfen:

xml = fromstring(xml) 

for page in xml: 
    for revision in page: 
     if revision.tag == "timestamp": 
      print(revision.text) 

Sie können findall alle Revisions-Tags zu erhalten verwenden und dann die Zeitstempel extrahieren:

In [1]: xml = """<page> 
    ...: <title>Zhuangzi</title> 
    ...: <ns>0</ns> 
    ...: <id>42870472</id> 
    ...: <revision> 
    ...:  <id>610251969</id> 
    ...:  <timestamp>2014-05-26T20:08:14Z</timestamp> 
    ...:  <contributor> 
    ...:   <username>White whirlwind</username> 
    ...:   <id>8761551</id> 
    ...:  </contributor> 
    ...:  <comment>TEXT</comment> 
    ...:  <model>wikitext</model> 
    ...: </revision> 
    ...: </page>""" 

In [2]: import xml.etree.ElementTree as ET 

In [3]: from StringIO import StringIO 

In [4]: tree = ET.parse(StringIO(xml)) 

In [5]: root = tree.getroot() 


In [6]: print([r.find("timestamp").text for r in root.findall("revision")]) 
['2014-05-26T20:08:14Z'] 

Wenn Sie lxml verwendet, Sie verwenden könnte einen einfachen XPath-Ausdruck:

from lxml.etree import parse,fromstring 

xml = """<page> 
    <title>Zhuangzi</title> 
    <ns>0</ns> 
    <id>42870472</id> 
    <revision> 
     <id>610251969</id> 
     <timestamp>2014-05-26T20:08:14Z</timestamp> 
     <contributor> 
     <username>White whirlwind</username> 
     <id>8761551</id> 
     </contributor> 
     <comment>TEXT</comment> 
     <model>wikitext</model> 
    </revision> 
</page>""" 


root = fromstring(xml) 

print(root.xpath("//revision/timestamp/text()")) 
['2014-05-26T20:08:14Z'] 

Mit dem, was Sie gebucht haben Sie benötigen ein Namespace-Mapping verwenden:

tree = ET.parse("your_xml") 
root = tree.getroot() 
ns = {"wiki":"http://www.mediawiki.org/xml/export-0.10/"} 


ts = [ts.text for ts in root.findall(".//wiki:revision//wiki:timestamp", ns) ] 

Vorausgesetzt, dass alle Revisions-Tags ein Timestamp-Tag haben.

Oder mit lxml mit einem XPath-:

from lxml.etree import parse 


tree = parse("your_fie") 
ns = {"wiki": "http://www.mediawiki.org/xml/export-0.10/"} 

print(tree.xpath("//wiki:revision//wiki:timestamp//text()",namespaces=ns)) 

Wenn Sie

tree = parse("test.xml") 

for elem in tree.getiterator(): 
    print elem.tag 

Die Ausgabe gedruckt ist:

{http://www.mediawiki.org/xml/export-0.10/}mediawiki 
{http://www.mediawiki.org/xml/export-0.10/}siteinfo 
{http://www.mediawiki.org/xml/export-0.10/}sitename 
{http://www.mediawiki.org/xml/export-0.10/}dbname 
{http://www.mediawiki.org/xml/export-0.10/}base 
{http://www.mediawiki.org/xml/export-0.10/}generator 
{http://www.mediawiki.org/xml/export-0.10/}case 
{http://www.mediawiki.org/xml/export-0.10/}namespaces 
{http://www.mediawiki.org/xml/export-0.10/}page 
............................. 

.

+0

XPath arbeitet mit lxml, aber die Frage ist markiert" elementtree ". – mzjn

+0

@mzjn, ja, falsch gelesen das Tag, aber die Logik und findall Arbeit genau das gleiche für xml –

+0

die 'print ([r.find (" timestamp "). Text für r in root.findall (" Revision ")])" 'druckt nichts Ich habe das Dokument importiert als 'tree = ET.parse (' 2articles.xml ') root = tree.getroot()' – Knokkelgeddon

0

Ich würde einfach so etwas wie:

import xml.etree.ElementTree as ET 
root = ET.parse('your_xml_file.xml') 
timestamp = root.find('.//timestamp').text 

Wenn Ihr xml mehr als ein Zeitstempel Element bekommen hat würde ich mit der letzten Zeile:

timestamps = [t.text for t in root.findall('.//timestamp')]