首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用XML::LibXML查找和替换CableLabs 1.0XML文件的特定部分

使用XML::LibXML查找和替换CableLabs 1.0XML文件的特定部分
EN

Stack Overflow用户
提问于 2013-06-16 12:28:38
回答 3查看 2K关注 0票数 1

我尝试过XML Simple,但由于它只是将XML读入散列,所以在对DTD运行时输出是无用的。用很难的方式学会的。

所以我采用了XML::LibXML,有趣的是,我发现用XML::Simple最难实现的要求却是最简单的。然而,我发现在XML::Simple中做一些更容易的事情被证明是不可能的(因为我对DOM缺乏理解,以及一些与XML::LibXML混淆的行为)。

下面是XML的一个示例:

代码语言:javascript
运行
复制
    <Metadata>
        <ADI Name="movie" />
        <App_Data Name="Something I don't care about" value="who cares" />
        <App_Data Name="Something I don't care about as well" value="who cares" />
        <App_Data Name="ChangeMe" Value="" />
    </Metadata>
    <Metadata>
        <ADI Name="photo" />
        <App_Data Name="Something I don't care about" value="who cares" />
        <App_Data Name="Something I don't care about as well" value="who cares" />
        <App_Data Name="ChangeMe" Value="" />
    </Metadata>
    <Metadata>
        <ADI Name="poster" />
        <App_Data Name="Something I don't care about" value="who cares" />
        <App_Data Name="Something I don't care about as well" value="who cares" />
        <App_Data Name="ChangeMe" Value="" />
    </Metadata>

注意:为了在这篇文章中使用,我对此进行了简化。

因此,基本上我必须使用<ADI>标记中的Name字段来确认我在DOM的正确区域中,以便对<App_Data>标记中的Value属性进行更改,即who's Name is ChangeMe

这是我想出来的代码片段……结果惨遭失败。

代码语言:javascript
运行
复制
#!/usr/bin/perl

use strict;
use XML::LibXML;

my $xml2 = XML::LibXML->new();
my $data = $xml2->parse_file("adi.xml");
my $movie;
my $photo;
my $poster;

foreach my $test ($data->findnodes('//Metadata')) {
    if ($test->findvalues('./ADI/@Name[.="movie"]')){
        $movie = 1;
        undef $photo;
        undef $poster;
    }
    elsif ($test->findvalues('./ADI/@Name[.="photo"]')){
        undef $movie;
        $photo = 1;
        undef $poster;
    }
    elsif ($test->findvalues('./ADI/@Name[.="poster"]')){
        undef $movie;
        undef $photo;
        $poster = 1;
    }
}

我没有更多的东西了,因为它不能工作。我得到一个类似于以下内容的错误

代码语言:javascript
运行
复制
Can't locate object method "findvalues" via package "XML::LibXML::Element"

作为这个问题的额外奖励,如果我想要完全删除包含照片和/或海报的<Metadata> (以及所有的孩子),该怎么办?

EN

Stack Overflow用户

发布于 2013-06-16 12:42:30

  • 你在哪里找到findvalues的?文档:

@nodes = $node->findnodes( $xpath_expression );$result = $node->find( $xpath );打印$node->findvalue( $xpath );

  • 为什么使用.这么多?

./ADI/@name.=“电影”

可能应该是

ADI@Name="movie"

  • You有多个元数据元素,但您可以仅根据最后一个元数据元素来设置变量。

  • 您不应该使用三个不同的变量来存储一段information.

代码语言:javascript
运行
复制
#!/usr/bin/perl

use strict;
use warnings;

use XML::LibXML qw( );

my $parser = XML::LibXML->new();
my $doc = $parser->parse_file("adi.xml");

for my $metadata ($doc->findnodes('//Metadata')) {
    my ($adi_type) = $metadata->find('ADI/@Name')
       or next;

    my ($app_data) = $metadata->find('App_Data[@Name="ChangeMe"]');

    if ($adi_type eq 'movie') {
       ...
    }
    elsif ($adi_type eq 'photo') {
       ...
    }
    elsif ($adi_type eq 'poster') {
       ...
    }
}

或者你甚至可以使用:

代码语言:javascript
运行
复制
my ($movie_adi) = $doc->findnodes('//Metadata[ADI/@Name="movie"]');
my ($movie_app_data) = $movie_adi->findnodes('App_Data[@Name="ChangeMe"]');
...

my ($photo_adi) = $doc->findnodes('//Metadata[ADI/@Name="photo"]');
my ($photo_app_data) = $photo_adi->findnodes('App_Data[@Name="ChangeMe"]');
...

my ($poster_adi) = $doc->findnodes('//Metadata[ADI/@Name="poster"]');
my ($poster_app_data) = $poster_adi->findnodes('App_Data[@Name="ChangeMe"]');
...
票数 2
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17130198

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档