【问题标题】:Perl script to populate an XML file用于填充 XML 文件的 Perl 脚本
【发布时间】:2015-10-06 18:41:57
【问题描述】:

我正在编写一个需要根据用户输入填充 XML 文件的 Perl 脚本。用户将提供国家名称和城市名称。如果他/她提供:japan 和 e,我需要在 japan 标签中填充它 - 但作为最后一个条目。我怎样才能最好地做到这一点?国家标签中的城市可以有很多。如何在相应的国家标签内添加城市作为最后一个标签?

每次我需要添加城市时,如何到达相关国家标签的末尾?

PS:我没有使用任何内置的数据结构来存储数据。我只是在文件中添加愚蠢的行。

示例输出 XML 文件:

<country name="japan-">
  <city>a</city>
  <city>b</city>
  <city>c</city>
  <city>d</city>
</country>
<country name="china-">
  <city>aa</city>
  <city>bb</city>
  <city>cc</city>
  <city>dd</city>
</country>

我有一个更具体的问题,Change an XML file content via Perl script

【问题讨论】:

    标签: xml perl


    【解决方案1】:

    XML::Simple 是……很简单。 :) 但它确实需要一个根元素:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    use XML::Simple;
    use Data::Dumper;
    
    my $xml = join "\n", <DATA>;
    my $doc = XMLin($xml, KeepRoot => 1);
    
    # Get the list of cities as a list, then push "Tokyo" to it.
    push @{$doc->{countries}->{country}->{'japan-'}->{city}}, 'Tokyo';
    
    print XMLout($doc, KeepRoot => 1);
    
    __DATA__
    <countries>
        <country name="japan-">
            <city>a</city>
            <city>b</city>
            <city>c</city>
            <city>d</city>
        </country>
        <country name="china-">
            <city>aa</city>
            <city>bb</city>
            <city>cc</city>
            <city>dd</city>
        </country>
    </countries>
    

    输出:

    <countries>
      <country name="china-">
        <city>aa</city>
        <city>bb</city>
        <city>cc</city>
        <city>dd</city>
      </country>
      <country name="japan-">
        <city>a</city>
        <city>b</city>
        <city>c</city>
        <city>d</city>
        <city>Tokyo</city>
      </country>
    </countries>
    

    【讨论】:

    • Great Mikael :) 如何解析现有的 xml 文件,然后向其中添加条目?
    • 感谢 Mikael,当用户要求添加一个尚不存在的国家/地区时,我还需要添加新的国家/地区。
    • 嗨 Mikael,我想我无法到达确切的节点。我的“推送”没有按预期工作。
    【解决方案2】:

    以下是使用XML::Twig 的解决方案。我认为它可以满足您的需求。它使用的 XML::Twig 最显着的特性是使用 id =&gt; name 选项将名称属性视为 ID,因此可以使用 $t-&gt;elt_id 直接找到元素,并使用 insert_new_elt 方法在那个树。它的签名是(&lt;position: before, after, first_child or last_child&gt;, &lt;tag_name&gt;, &lt;{attributes}&gt;, &lt;content&gt;),

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    use XML::Twig;
    
    my $t= XML::Twig->new( id => 'name',  # treat the name attribute as an ID
                           pretty_print => 'indented'
                         )
                    ->parse( \*DATA);
    
    add_city( $t, japan => "Kobe");
    add_city( $t, japan => "Tokyo");
    add_city( $t, china => "Beijing");
    add_city( $t, china => "Shanghai");
    add_city( $t, japan => "Kobe");
    add_city( $t, south_korea => "Seoul");
    
    $t->print;
    
    sub add_city
      { my( $t, $country_name, $city_name)= @_;
    
        my $country= $t->elt_id( $country_name);
        if( ! $country)
          { warn "creating country '$country_name'\n"; 
            $country= $t->root->insert_new_elt( last_child => country 
                                                => { name => $country_name }
                                              );
          }
    
        if( $country->first_child( qq{city[text()="$city_name"]}))
          { warn "city '$city_name' already found in '$country_name', skipping\n"; 
            return;
          }
    
        warn "adding '$city_name' to '$country_name', skipping\n";
        $country->insert_new_elt( last_child => 'city', $city_name);
      }
    
    
    __DATA__
    <countries>
      <country name="japan">
      </country>
      <country name="china">
      </country>
    </countries>
    

    【讨论】:

    • 感谢 Mirod 的回答。就我而言,我需要对现有的 xml 文件进行更改(添加)。如何加载我现有的 xml 文件?
    • 感谢您的帮助。我在这里发布了更具体的问题:stackoverflow.com/questions/4301435/…
    • 调用parse方法时会加载xml文件。然后,您可以通过导航访问元素,使用 first/last_child、children、parent 或 prev/next_siblin,直接使用 elt_id 或使用带有 findnodes、finvalue 的 XPath...
    【解决方案3】:

    我认为您的意思是:如何加载 XML 文件并根据用户输入向其中添加条目?

    如果我理解正确:您使用 XML::Simple 之类的解析器/编写器(显然也有像 XML::Twig 这样更好的解析器/编写器,所以请稍微探索一下)将文件加载到 Perl 哈希数据结构中,然后数组。 (使用 Data::Dumper 检查它在内存中的样子。)然后使用正常的 Perl 数据交互编辑该结构,完成后使用编写器将其转换回 XML。

    【讨论】:

    • 很抱歉给您带来了困惑。我知道如何编写 xml 内容。我的问题是关于如何将城市添加为国家标签中的最后一个条目。我是否需要遍历所有现有的城市条目,当我到达最后一个标签时,我需要在那里添加新请求的城市。如何做到这一点?
    • 呃,如果您使用解析器读取 XML 文件,您将获得国家/地区的哈希值,按键排序(在最好的情况下),每个国家/地区都包含一个城市数组。因此,您只需从国家哈希中选择正确的值,获取其城市数组并推送到该数组。困难在哪里?
    • 感谢 Mithaldu,我仍在学习在 perl 中使用 XML。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多