【问题标题】:Extract data from an XML file with XML::LibXML使用 XML::LibXML 从 XML 文件中提取数据
【发布时间】:2017-05-31 23:24:26
【问题描述】:

我有一个这样的 XML 文件,其中包含数千个条目

<mediawiki>
  <page>
    <title>page1</title>
    <revision>
      <id>2621</id>
      <parentid>6</parentid>
      <timestamp>2005-10-09T01:00:18Z</timestamp>
      <contributor>
        <username>Chaos</username>
        <id>2</id>
      </contributor>
      <model>wikitext</model>
      <format>text/x-wiki</format>
      <text xml:space="preserve">text1</text>
    </revision>
  </page>
  <page>
    <title>page2</title>
    <ns>8</ns>
    <id>7</id>
    <revision>
      <id>2619</id>
      <parentid>2618</parentid>
      <timestamp>2005-10-09T00:56:39Z</timestamp>
      <contributor>
        <username>Chaos</username>
        <id>2</id>
      </contributor>
      <model>wikitext</model>
      <format>text/x-wiki</format>
      <text xml:space="preserve">text2</text>
    </revision>
  </page>
  <page>
    <title>page3</title>
    <ns>8</ns>
    <id>6</id>
    <revision>
      <id>2621</id>
      <parentid>6</parentid>
      <timestamp>2005-10-09T01:00:18Z</timestamp>
      <contributor>
        <username>Chaos</username>
        <id>2</id>
      </contributor>
      <model>wikitext</model>
      <format>text/x-wiki</format>
      <text xml:space="preserve">text3</text>
    </revision>
  </page>
</mediawiki>

通过我的脚本,每个页面都必须在一个文本文件中,其名称为标签&lt;title&gt;的内容并包含&lt;text xml:space="preserve"&gt;&lt;/text&gt;的文本

我的代码

my $filename = "pages.xml";
my $parser   = XML::LibXML->new();
my $xmldoc   = $parser->parse_file( $filename );
my $file;

foreach my $page ( $xmldoc->findnodes( '/mediawiki/page' ) ) {

    foreach my $title ( $page->findnodes( '/mediawiki/page/title' ) ) {

        foreach my $rev ( $page->findnodes( '/mediawiki/page/revision' ) ) {

            foreach my $text ( $rev->findnodes( 'text/text()' ) ) {

                $file = $title->to_literal();
                my $newfile = "$file.txt";

                open( my $out, '>:utf8', $newfile )
                        or die "Unable to open '$newfile' for write: $!";
                my $texte = $text->data;
                print $out "$text\n";
                close $out;
            }
        }
    }
}

问题是每个构造的文件都包含与最后一个标签&lt;text xml:space="preserve"&gt;&lt;/text&gt;相同的文本

【问题讨论】:

  • 我已经修复了您帖子的格式并为您的代码添加了一些缩进。非常欢迎您,但请您以后自己努力做到这一点。如果您要让很多人阅读和理解您的帖子,请尽量让其清晰易读。
  • @DaveCross:很抱歉撤销了你所有的好工作。使用平板电脑修改帖子时,我似乎没有收到任何更新的通知。
  • @Borodin:不用担心。我以为这是一场意外。
  • @rim:请确保编辑您问题的最新版本。我不确定您为什么要进行更改,因为您似乎所做的只是从 XML 中删除一页。我恢复了 Dave Cross 和我所做的编辑,并在重新格式化后添加了您的新 XML。
  • @rim:请看What should I do when someone answers my question?。我不希望立即接受;事实上,我建议您等待一两天,以防出现更好的答案。但你至少可以承认我的回答并解释我的假设是否正确。

标签: xml perl xml-libxml


【解决方案1】:

您的错误是嵌套所有 for 循环而不使用相对 XPath 表达式

这应该做你想做的事

use utf8;
use strict;
use warnings 'all';
use feature 'say';

STDOUT->autoflush;

use XML::LibXML;

my $filename = "pages.xml";
my $doc      = XML::LibXML->load_xml( location => $filename );

for my $page ( $doc->findnodes('/mediawiki/page') ) {

    my ($title) = $page->findnodes('title');
    my $file = $title->textContent;

    my ($rev_text) = $page->findnodes('revision/text');
    my $text = $rev_text->textContent;

    open my $fh, '>:utf8', $file
        or die qq{Unable to open "$file" for output: $!};

    print $fh "$text\n";

    close $fh;

    say qq{File "$file" written with "$text"};
}

输出

File "page1" written with "text1"
File "page2" written with "text2"
File "page3" written with "text3"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 2013-03-20
    • 2013-05-11
    • 1970-01-01
    相关资源
    最近更新 更多