【问题标题】:How to use perl script filter xml tags when there has some same tag names?当有一些相同的标签名称时,如何使用 perl 脚本过滤 xml 标签?
【发布时间】:2020-05-12 12:43:46
【问题描述】:

我正在使用命令行进行过滤,下面是我的 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>

如你所见,我想要“numbers”下的“value”标签中的值,但是当我使用我的perl代码过滤它时,“extra”标签下的“value”也会出现,我应该怎么做只保留“数字”下的“价值”标签并删除“额外”下的“价值”标签???

下面是我的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>

是的,“extra”标签被删除了,但是“extra”标签中的“value”标签还在,我不想要它们,请帮我编辑我的命令行代码,非常感谢!!!

【问题讨论】:

    标签: xml perl


    【解决方案1】:

    当已经存在优秀的 XML 解析器时,花费大量时间和精力编写自己的 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');
    

    【讨论】:

      猜你喜欢
      • 2023-03-06
      • 2020-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-18
      • 2023-04-09
      • 1970-01-01
      相关资源
      最近更新 更多