Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Perl将标记名和值从XML转换为HTML_Html_Xml_Perl - Fatal编程技术网

如何使用Perl将标记名和值从XML转换为HTML

如何使用Perl将标记名和值从XML转换为HTML,html,xml,perl,Html,Xml,Perl,有没有办法使用Perl将一个简单的XML文档转换成HTML,从而为我提供一个标记名和标记值表 XML文件output.XML如下所示 <?xml version="1.0"?> <doc> <GI-eSTB-MIB-NPH> <eSTBGeneralErrorCode.0>INTEGER: 0</eSTBGeneralErrorCode.0> <eSTBGeneralConnectedSt

有没有办法使用Perl将一个简单的XML文档转换成HTML,从而为我提供一个标记名和标记值表

XML文件
output.XML
如下所示

<?xml version="1.0"?>

<doc>
    <GI-eSTB-MIB-NPH>
        <eSTBGeneralErrorCode.0>INTEGER: 0</eSTBGeneralErrorCode.0>
        <eSTBGeneralConnectedState.0>INTEGER: true(1)</eSTBGeneralConnectedState.0>
        <eSTBGeneralPlatformID.0>INTEGER: 2076</eSTBGeneralPlatformID.0>
        <eSTBGeneralFamilyID.0>INTEGER: 25</eSTBGeneralFamilyID.0>
        <eSTBGeneralModelID.0>INTEGER: 60436</eSTBGeneralModelID.0>
        <eSTBMoCAMACAddress.0>STRING: 0:0:0:0:0:0</eSTBMoCAMACAddress.0>
        <eSTBMoCANumberOfNodes.0>INTEGER: 0</eSTBMoCANumberOfNodes.0>
    </GI-eSTB-MIB-NPH>
</doc>
1. eSTBGeneralPlatformID.0 - INTEGER: 2076
2. eSTBGeneralFamilyID.0 - INTEGER: 25
3. 
我试图使用来自web的代码,但我真的很难理解如何为HTML标记生成所需的格式

我试的是这个

#!/usr/bin/perl

use strict;
use warnings;

use XML::Parser;
use XML::LibXML;

#Add TagNumberConversion.pl here

my $parser = XML::Parser->new();
$parser->setHandlers(
    Start => \&start,
    End   => \&end,
    Char  => \&char,
    Proc  => \&proc,
);

my $header = &getXHTMLHeader();
print $header;

$parser->parsefile( '20150630104826.xml' );

my $currentTag = "";

sub start() {

    my ( $parser, $name, %attr ) = @_;
    $currentTag = $name;

    if ( $currentTag eq 'doc' ) {
        print "<head><title>"
            . "Output of snmpwalk for cpeIP4"
            . "</title></head>";
        print "<body><h2>" . "Output of snmpwalk for cpeIP4" . "</h2>";
        print '<table summary="'
            . "Output of snmpwalk for cpeIP4"
            . '"><tr><th>Tag Name</th><th>Tag Value</th></tr>';
    }
    elsif ( $currentTag eq 'GI-eSTB-MIB-NPH' ) {
        print "<tr>";
    }
    elsif ( $currentTag =~ /^eSTB/ ) {
        print "<tr>";
    }
    else {
        print "<td>";
    }
}

sub end() {

    my ( $parser, $name, %attr ) = @_;
    $currentTag = $name;

    if ( $currentTag eq 'doc' ) {
        print "</table></body></html>";
    }
    elsif ( $currentTag eq 'GI-eSTB-MIB-NPH' ) {
        print "</tr>";
    }
    elsif ( $currentTag =~ /^eSTB/ ) {
        print "</tr>";
    }
    else {
        print "</td>";
    }
}

sub char() {
    my ( $parser, $data ) = @_;

    print $data;
}

sub proc() {
    my ( $parser, $target, $data ) = @_;

    if ( lc( $target ) eq 'perl' ) {
        $data = eval( $data );
        print $data;
    }
}

sub getXHTMLHeader() {

    my $header = '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';

    return $header;
}
#/usr/bin/perl
严格使用;
使用警告;
使用XML::解析器;
使用XML::LibXML;
#在此处添加TagNumberConversion.pl
my$parser=XML::parser->new();
$parser->setHandlers(
开始=>\&Start,
End=>\&End,
Char=>\&Char,
Proc=>\&Proc,
);
my$header=&getXHTMLHeader();
打印$header;
$parser->parsefile('20150630104826.xml');
我的$currentTag=“”;
次启动(){
我的($parser,$name,%attr)=@;
$currentTag=$name;
如果($currentTag eq‘doc’){
打印“”
“cpeIP4的snmpwalk输出”
. "";
打印“cpeIP4的snmpwalk输出”;
打印“标签名称标签值”;
}
elsif($currentTag eq'GI eSTB MIB NPH'){
打印“”;
}
elsif($currentTag=~/^eSTB/){
打印“”;
}
否则{
打印“”;
}
}
副端(){
我的($parser,$name,%attr)=@;
$currentTag=$name;
如果($currentTag eq‘doc’){
打印“”;
}
elsif($currentTag eq'GI eSTB MIB NPH'){
打印“”;
}
elsif($currentTag=~/^eSTB/){
打印“”;
}
否则{
打印“”;
}
}
子字符(){
我的($parser,$data)=@;
打印$数据;
}
副程序(){
我的($parser,$target,$data)=@;
if(lc($target)eq‘perl’){
$data=评估($data);
打印$数据;
}
}
子getXHTMLHeader(){
我的$1
';
返回$header;
}
这是正在编写的代码,但我意识到这对于我的需求来说是过分的

因此,我试图找出是否有任何快速的方法可以使用Perl来实现这一点


如果真的有快速的方法,请给我一些提示。

快速而肮脏的方法就是只使用正则表达式。但是,它有丢失一些数据并被边缘案例烧毁的风险。但既然是你自找的

#!/usr/bin/env perl

use strict;

open my $fh, 'filename.xml'
    or die "unable to open filename.xml : $!";
my $count = 1;
print "<head><title>'Output of snmpwalk for cpeIP4'</title></head>\n";
print "<body><h2>'Output of snmpwalk for cpeIP4'</h2>\n";
print "<table summary='Output of snmpwalk for cpeIP4'><tr><th>Tag Name</th><th>Tag Value</th></tr>\n";
while (my $line = <$fh>) {
    next unless $line =~ m|<eSTB|;
    # Store into into $tag and $value
    # the result of matching whitespace, followed by '<'
    # followed by anything (store into $tag)
    # followed by '>'
    # followed by anything (store into $value)
    # followed by '<'
    my ($tag, $value) = $line =~ m|\s+<(.+?)>(.+?)<|;
    print "<tr><td>" . $count++ . ". $tag</td><td>$value</td></tr>\n";
}
print "</table></body></html>\n";
#/usr/bin/env perl
严格使用;
打开我的$fh,'filename.xml'
或者“无法打开filename.xml:$!”;
我的$count=1;
打印“'cpeIP4的snmpwalk输出'\n”;
打印“'cpeIP4的snmpwalk输出'\n”;
打印“标签名称标签值\n”;
while(我的$line=){

接下来,除非$line=~m |首先,我认为您在这方面使用了错误的工具。我总是发现比XML::Parser更容易使用。您加载XML::LibXML,但从未使用过它

第二,我认为如果你把这看作两个阶段,你会发现你的生活更容易——一个是提取数据,另一个是输出新数据

这是第一个阶段,它将需要的数据存储在一个数组中

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use XML::LibXML;
use Data::Dumper;

my $file = shift || die "Must give XML file\n";

my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($file);

my @tags;

# Find the nodes using an XPath expression
foreach ($doc->findnodes('//GI-eSTB-MIB-NPH/*')) {
  push @tags, { name => $_->nodeName, content => $_->textContent };
}

# Just here to show the intermediate data structure
say Dumper \@tags;
然后,您需要使用
@tags
来生成输出。十五年来,我们都知道在Perl代码中包含硬编码HTML是一个糟糕的想法,因此我强烈建议您使用类似的模板系统

我创建了一个
xml.tt
文件,如下所示:

<html>
<head>
<title>Output of snmpwalk for cpeIP4</title>
</head>
<body><h2>Output of snmpwalk for cpeIP4</h2>
<table summary='Output of snmpwalk for cpeIP4'>
<tr>
<th>Tag Name</th><th>Tag Value</th><
/tr>
[% FOREACH tag IN tags -%]
<tr><td>[% loop.count %]. [% tag.name %]</td><td>[% tag.content %]</td></tr>
[% END -%]
</table>
</body>
</html>
use Template;

my $tt = Template->new;
$tt->process('xml.tt', { tags => \@tags });

我希望您同意,所有这些看起来都比您的方法简单得多。

谢谢Dave。我同意您提供的解决方案比我尝试的解决方案更简洁。不过,我认为我没有“模板”的支持模块。我收到的错误是:无法在@INC中找到Template.pm(@INC包含:/usr/local/lib64/perl5/usr/local/share/perl5/usr/lib64/perl5/vendor\u perl/usr/share/perl5/vendor\u perl/usr/lib64/perl5/usr/share/perl5。)在调用\u至\u snmpwalk\u V_8.pl第14行时。开始失败-在调用\u至\u snmpwalk\u V_8.pl第14行时编译中止。我正在试图找到如何更正此错误。我已经包含了use 5.010,我使用perl v5.10.1声音,就像您没有安装模板模块一样。您只需要通过任何方式安装它来安装CPAN模块s、 非常感谢xxx。我使用了你快速而肮脏的方式,它完美地完成了工作。不过,我正在尝试理解下面这一行,我认为这是在进行模式匹配和其他一些操作,比如将$line的特定部分放入$tag和$value字符串中:my($tag,$value)=$line=~m|\s+(.+)1.存储到变量$tag和$value中2.模式匹配的结果$line 3.匹配空格,后跟一个“”,后跟任何内容6.捕获$value中的'anything'。后跟'Hmm…使用正则表达式解析XML。这从来不会出错:-/Dave,我尝试安装模板模块,以便使用LibXML而不是正则表达式,but发现CPAN没有安装(或者至少现在不工作)在我使用的Linux设备上。但我会让CPAN工作,并使用LibXML进行解析,因为这对我来说是一种更可靠的方法,也是一种很好的学习方式。没有Tempalte工具包不会阻止您使用XML::LibXML解析XML。您只需要使用不同的方法来创建输出。您不应该使用ampersand
&
当您调用Perl子例程时——just
my$header=getXHTMLHeader()
是正确的。并且当您定义子例程时不应该使用原型——那些子例程名称后面的
确保没有传递任何参数,这根本不是您想要的。just
sub start{…}
是正确的。您应该为全局标识符(如包名)保留大写字母——本地标识符应该由小写字母、十进制数字和下划线组成。如果您显示希望作为输出的实际HTML,这将非常有帮助
use Template;

my $tt = Template->new;
$tt->process('xml.tt', { tags => \@tags });