Copy data inside one field XML

戏子无情 提交于 2020-01-25 21:31:53

问题


I have some lines like:

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

I need copy the value of xmltv_id into site_id like this:

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

I was thinking to use SED but I am in the trouble.

Thank you in someone want help me!


回答1:


As Ruslan Osmanov pointed out, the tool for this kind of job is xmlstarlet. The most obvious solution would be:

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

However, that does not seem to work in my version of xmlstarlet. You can work around the problem, however:

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



回答2:


Don't use sed. It's the wrong tool for the job. XML is contexual, and regular expressions are not.

Perl can do it, with an XML parsing library (I like 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;

This reads your file, and prints the changed file to 'stdout', so you can verify it.

If you're feeling a bit more bold, you can use parsefile_inplace - but note, you should be a bit more careful about this, because you can clobber your original file:

#!/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');


来源:https://stackoverflow.com/questions/41850778/copy-data-inside-one-field-xml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!