使用perl需要list中label元素的最大值

时间:2016-05-04 09:44:40

标签: regex perl

以下提供的列表包含嵌套列表。我需要在< label>中获取最大级别值元素并在< list>之前插入值属性显示为' type =" num"'。

例如:

INPUT:

 <list spitype="num" id="list1">
    <list-item><label>1</label><para></para></list-item>
    <list-item><label>2</label><para></para>
       <list spitype="num" id="list1-1">
      <list-item><label>1</label><para></para></list-item>
      <list-item><label>2</label><para></para></list-item>
      <list-item><label>3</label><para></para></list-item>
       </list></list-item>
    <list-item><label>3</label><para></para></list-item>
    <list-item><label>4</label><para></para></list-item>
    <list-item><label>5</label><para></para></list-item>
 </list>

输出:

 **<max-val-5/>**
 <list spitype="num" id="list1">
    <list-item><label>1</label><para></para></list-item>
    <list-item><label>2</label><para></para>
         **<max-val-3/>**
     <list spitype="num" id="list1-1">
      <list-item><label>1</label><para></para></list-item>
      <list-item><label>2</label><para></para></list-item>
      <list-item><label>3</label><para></para></list-item>
       </list></list-item>
    <list-item><label>3</label><para></para></list-item>
    <list-item><label>4</label><para></para></list-item>
    <list-item><label>5</label><para></para></list-item>
 </list>

我在下面写了这段代码,但是我没有得到输出。嵌套列表并未涵盖在此列表中。你能不能请任何人都能帮忙解决这个问题。

$incnt=~s{(<list(?: |>)[^>]*>((?:(?!<\/list>).)*)<\/list>)}{
my $list=$1; my ($sbpre,$sbmatch,$sbpost,$slmatch,$LblWidthVal) = "";
if($list=~m/<list(?: |>)[^>]*type="num"[^>]*>/g)
{
    $sbpre=$sbpre.$`; $sbmatch=$&; $sbpost=$';
    $slmatch=$1 while($list=~m/<label>([^<>]*)<\/label>/sg);
    $slmatch=~s/[.,:;\(\)\[\]\{\}]*//g;
    $LblWidthVal = "<max-val-$slmatch/>";
    $sbmatch = $LblWidthVal."\n".$sbmatch;
    $sbpre = $sbpre.$sbmatch; $list = $sbpost;
}
if(length $sbpre) {  $list = $sbpre.$sbpost;  }
"$list";}igse;

1 个答案:

答案 0 :(得分:5)

虽然可以添加名称为max-val-5的新XML元素,但将信息放入元素的名称是非常不规则的。在XML元素中包含两个根元素也是非法的,因此我将代码包装在<root>...</root>元素中并添加了一个看起来像`

的新元素

此解决方案使用XML::Twig模块,我认为它比XML::LibXML更容易使用,特别是对于输出XML,并且在单个页面上具有所有文档

我希望你会同意与正则表达式解决方案相比它非常简单

use strict;
use warnings 'all';

use XML::Twig;
use List::Util 'max';

my $twig = XML::Twig->new( pretty_print => 'indented' );
$twig->parsefile('test.xml');

my $max_label = max $twig->findvalues('//label');

my $max_element = XML::Twig::Elt->new( max => { value => $max_label } );

$max_element->paste( first_child => $twig->root);

$twig->print;

输出

<root>
  <max value="5"/>
  <list id="list1" spitype="num">
    <list-item>
      <label>1</label>
      <para></para>
    </list-item>
    <list-item>
      <label>2</label>
      <para></para>
      <list id="list1-1" spitype="num">
        <list-item>
          <label>1</label>
          <para></para>
        </list-item>
        <list-item>
          <label>2</label>
          <para></para>
        </list-item>
        <list-item>
          <label>3</label>
          <para></para>
        </list-item>
      </list>
    </list-item>
    <list-item>
      <label>3</label>
      <para></para>
    </list-item>
    <list-item>
      <label>4</label>
      <para></para>
    </list-item>
    <list-item>
      <label>5</label>
      <para></para>
    </list-item>
  </list>
</root>