【问题标题】:Copy data inside one field XML在一个字段 XML 中复制数据
【发布时间】:2017-06-10 14:02:56
【问题描述】:

我有一些类似的行:

<channel update="i" site="merge-xmltv" site_id="" xmltv_id="Rai 1">Rai 1</channel>
<channel update="i" site="merge-xmltv" site_id="" xmltv_id="Rai 1 +2HD">Rai 1 +2HD</channel>
<channel update="i" site="merge-xmltv" site_id="" xmltv_id="Rai 1 +1HD">Rai 1 +1HD</channel>

我需要像这样将xmltv_id 的值复制到site_id 中:

<channel update="i" site="merge-xmltv" site_id="Rai 1" xmltv_id="Rai 1">Rai 1</channel>
<channel update="i" site="merge-xmltv" site_id="Rai 1 +2HD" xmltv_id="Rai 1 +2HD">Rai 1 +2HD</channel>
<channel update="i" site="merge-xmltv" site_id="Rai 1 +1HD" xmltv_id="Rai 1 +1HD">Rai 1 +1HD</channel>

我正在考虑使用 SED,但我遇到了麻烦。

谢谢有人想要帮助我!

【问题讨论】:

标签: xml linux shell replace sed


【解决方案1】:

正如 Ruslan Osmanov 所指出的,这种工作的工具是xmlstarlet。最明显的解决方案是:

xmlstarlet ed -u "//channel/@site_id" -x "../@xmltv_id" input

但是,这在我的xmlstarlet 版本中似乎不起作用。但是,您可以解决此问题:

xmlstarlet ed -u "//channel/@site_id" -x "string(../@xmltv_id)" input

【讨论】:

  • 我需要付给你一杯啤酒 :D :D :D
【解决方案2】:

不要使用 sed。这是工作的错误工具。 XML 是上下文相关的,而正则表达式不是。

Perl 可以做到这一点,它带有一个 XML 解析库(我喜欢 XML::Twig)。

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig;

#load your XML
my $twig = XML::Twig -> new;
   $twig -> parsefile ('test3.xml'); 

#iterate all 'channel' nodes. 
foreach my $channel ( $twig -> get_xpath('//channel') ) {
     #replace a blank site ID
    if ( $channel -> att('site_id') eq "" ) {
       #with the content of xmltv_id attribute
       $channel -> set_att('site_id', $channel->att('xmltv_id'));
    }
}

$twig -> set_pretty_print('indented');
$twig -> print;

这会读取您的文件,并将更改的文件打印到“stdout”,以便您验证它。

如果您感觉更大胆,可以使用parsefile_inplace - 但请注意,您应该对此更加小心,因为您可能会破坏您的原始文件:

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig -> new ( pretty_print => 'indented_a',
                              twig_handlers => { 
                                'channel' => sub { 
                                    $_ -> set_att('site_id', $_->att('xmltv_id')); 
                                    $_ -> flush }
                              } ) -> parsefile_inplace('test3.xml');

【讨论】:

  • 我尝试了您的解决方案,但我使用的是 CGWIN,但我无法使用 Twig :( :(
  • Strawberry perl 捆绑了它。这是我在 Windows 上使用的。但是由于 Windows 文件锁定,“就地编辑”不一定能很好地工作,因此打印到(新)文件并重命名可能是要走的路。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-20
  • 1970-01-01
相关资源
最近更新 更多