Как использовать perl скрипт фильтра xml теги, когда есть несколько одинаковых имен тегов? - PullRequest
0 голосов
/ 27 января 2020

Я использую командную строку для выполнения фильтрации, ниже мой XML файл

<data>
    <numbers>
        <value>1</value>
        <extra>
            <value>a</value>
        </extra>
    </numbers>
    <numbers>
        <value>2</value>
        <extra>
            <value>b</value>
        </extra>
    </numbers>
    <numbers>
        <value>3</value>
    </numbers>
    <numbers>
        <value>10</value>
        <extra>
            <value>c</value>
        </extra>
    </numbers>
    <numbers>...</numbers>
    ...
</data>

Как видите, я хочу, чтобы значения в теге "value" находились в разделе "numbers", но когда Я использую мой код perl для его фильтрации, также появятся «значение» под «дополнительными» тегами, как мне сделать, чтобы просто сохранить тег «значение» под «числами» и удалить теги «значение», которые находятся под "extra" ???

ниже мой perl код: (формат командной строки)

perl -nle 'while(<stdin>){if(/data|numbers|value/){chop; print}}' < sample.xml > output.xml

вывод этой командной строки:

<data>
    <numbers>
        <value>1</value>
            <value>a</value>
    </numbers>
    <numbers>
        <value>2</value>
            <value>b</value>
    </numbers>
    <numbers>
        <value>3</value>
    </numbers>
    <numbers>
        <value>10</value>
            <value>c</value>
    </numbers>
    <numbers>...</numbers>
    ...
</data>

Да, «лишние» теги удалены, но теги «value» в «extra» тегах все еще есть, я не хочу их, пожалуйста, помогите мне отредактировать мой код командной строки, большое спасибо !! !

1 Ответ

4 голосов
/ 27 января 2020

Нет смысла тратить много времени и усилий на написание собственного XML парсера, когда великие уже существуют.


Чёрный список

Чтобы удалить extra элементов:

use XML::LibXML qw( );

my $doc = XML::LibXML->new->parse_file('sample.xml');

for my $node ($doc->findnodes('/data/numbers/extra')) {
   $node->unbindNode();
}

$doc->toFile('output.xml');

Подход из белого списка

Чтобы удалить все элементы, кроме тех, которые, как вы сказали, вы хотели сохранить:

use XML::LibXML qw( );

sub qualified_name {
   my ($node) = @_;
   if (defined($node->namespaceURI())) {
      return sprintf("{%s}%s", $node->namespaceURI(), $node->nodeName());
   } else  {
      return $node->nodeName();
   }
}

my $doc = XML::LibXML->new->parse_file('sample.xml');

for my $node ($doc->findnodes('/data/*')) {
   if (qualified_name($node) ne "numbers") {
      $node->unbindNode();
      next;
   }

   for my $node ($node->findnodes('*')) {
      if (qualified_name($node) ne "value") {
         $node->unbindNode();
         next;
      }
   }
}

$doc->toFile('output.xml');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...