【问题标题】:Extract data from XML file if arguments are of certain values如果参数具有特定值,则从 XML 文件中提取数据
【发布时间】:2016-03-31 12:39:24
【问题描述】:

我想循环浏览 XML 格式的 Wikipedia 转储,并且对于每个修订,如果修订是由某个用户名进行的,我想保存时间戳和注释。这可能吗?我正在尝试熟悉 lxml。

<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>

【问题讨论】:

  • 您找到了哪些工具来读取 XML 数据以及您尝试使用哪些代码来完成您的要求?

标签: python xml lxml


【解决方案1】:
import xmltodict 


xml_input = """
<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-25T20:08:14Z</timestamp>
        <contributor>
            <username>Patric</username>
            <id>8761551</id>
        </contributor>
    </revision>
    <revision>
        <id>610251969</id>
        <timestamp>2014-05-26T20:08:14Z</timestamp>
        <contributor>
            <username>Don</username>
            <id>8761551</id>
        </contributor>
    </revision>
    <revision>
        <id>610251969</id>
        <timestamp>2014-05-27T20:08:14Z</timestamp>
        <contributor>
            <username>Patric</username>
            <id>8761551</id>
        </contributor>
    </revision>                
</page>
</mediawiki>
"""


dic_xml = xmltodict.parse(xml_input)

for rev in dic_xml['mediawiki']['page']['revision']:
    if rev['contributor']['username'] == 'Patric':
        print rev['id']
        print rev['timestamp']

使用您的文件:

import xmltodict
with open('/home/jurkij/Downloads/testarticles.xml') as xml_file:
    dic_xml = xmltodict.parse(xml_file.read())
    for page in dic_xml['mediawiki']['page']:
        for rev in  page['revision']:
            if 'username' in rev['contributor'] and rev['contributor']['username'] == 'Aristophanes68':
                print rev['timestamp']
                print rev['id']

【讨论】:

  • 看起来不错,但我无法使用 dic_xml = xmltodict.parse(open('2articles.xml', encoding='latin-1').read())
  • 你能上传你的xml并粘贴链接吗?
  • 您的问题到底是什么?我可以毫无困难地解析它。父标签贡献者中缺少关键用户名只有一个问题,我在 rev['contributor'] cond 中使用 'username' 修复了这个问题。
【解决方案2】:

是的,这可以使用 lxml。

您知道要查找的节点(从版本的用户名开始),因此编写代码来选择该节点并将该值与您要查找的已知名称进行比较。

完成该部分后,保存时间戳和注释应该很简单。

您将在 lxml 文档 (http://lxml.de/) 中找到您需要的内容;查看“XPath”部分以了解如何选择所需的节点(这将包括将 XML 加载到脚本中的 sn-ps)

您可能还希望查阅 lxml 链接 (http://effbot.org/zone/element.htm) 的 ElementTree 教程,以了解如何使用通过 XPath 或其他方法找到的 XML 元素。这对于从元素中获取值很有用。

【讨论】:

    【解决方案3】:

    last question 继续,您可以使用 lxml 和 xpath 表达式轻松完成:

    from lxml.etree import parse
    
    tree = parse("test.xml")
    
    ns = {"wiki": "http://www.mediawiki.org/xml/export-0.10/"}
    revs = tree.xpath("//wiki:revision[.//wiki:username='White whirlwind']",namespaces=ns)
    
    print([(rev.xpath(".//wiki:timestamp//text()", namespaces=ns)[0],rev.xpath(".//wiki:username//text()", namespaces=ns)[0]) for rev in revs])
    

    对于以下xml:

    <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>
                     <id>610251969</id>
                <timestamp>2014-06-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>     <id>610251969</id>
                <timestamp>2014-07-26T20:08:14Z</timestamp>
                <contributor>
                    <username>foobar</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>
    
            </page>
    

    输出:

     [[('2014-05-26T20:08:14Z', 'White whirlwind'), ('2014-06-26T20:08:14Z', 'White whirlwind')]
    

    //wiki:revision[.//wiki:username='White whirlwind'] 查找所有包含用户名且用户名值为White whirlwind 的修订标签,您将看到它返回2,因为foo 不匹配,您只需要从中提取时间戳和用户名值revs 中过滤的修订版本。

    对于您的file in google drive,它会返回:

    [('2014-05-26T20:08:14Z', 'White whirlwind'), 
    ('2014-05-26T20:12:49Z', 'White whirlwind'),
     ('2014-05-26T20:13:04Z', 'White whirlwind'),
    ('2014-05-31T21:14:15Z', 'White whirlwind'), 
    ('2015-10-11T19:24:46Z', 'White whirlwind'),
     ('2015-10-11T19:26:31Z', 'White whirlwind')]
    

    如果你检查你的文件是正确的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-11
      • 2014-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-27
      • 2015-03-04
      • 2013-01-06
      相关资源
      最近更新 更多