Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.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文档的元素(includng属性)和文本节点_Xml_Perl - Fatal编程技术网

使用perl解析xml文档的元素(includng属性)和文本节点

使用perl解析xml文档的元素(includng属性)和文本节点,xml,perl,Xml,Perl,我有以下test.xml文件: <root> <A title="A1"> <B title="B1"> <C title="C1"> <params>param=ABC1</params> <params>param=ABC2</params> </C> </B> </A> <D title="D1"> <

我有以下test.xml文件:

<root>
<A title="A1">
  <B title="B1">
   <C title="C1">
    <params>param=ABC1</params>
    <params>param=ABC2</params>
   </C>
  </B>
</A>
<D title="D1">
  <B title="B2">
   <C title="C2">        
     <params>param=DBC1</params>
     <params>param=DBC2</params>
   </C>
  </B>
</D>
</root>
我尝试过使用
getElementByTagName('param')
getNodeChilds
等。。。没有成功。另外,我一直在使用的是模块

代码如下:

 use XML::DOM;
 my $parser = new XML::DOM::Parser;
 my $doc = $parser->parsefile("test.xml");
 my @paramarray=();
 ParseXML($doc,"");

sub ParseXML{
 my $node = $_[0];
 my $indent = $_[1];
 my $title;

 if ($node == null) {
  return;
 }

 my $type = $node->getNodeType();
 if ($type == DOCUMENT_NODE) {
  ParseXML($node->getFirstChild(),"");
  break;
 }  

  if ($type == ELEMENT_NODE) {
  $numberAttributes =0;
  if ($node->getAttributes() !=null){
     $numberAttributes = $node->getAttributes()->getLength();
  }

 for ($loopIndex =0; $loopIndex<$numberAttributes; $loopIndex++) {
     $attribute = ($node->getAttributes())->item($loopIndex);
     if($attribute->getNodeName() eq "title"){
      $title = $attribute->getNodeValue();
     }
 }

 if ($node->getNodeName() eq "params"){
  foreach my $paramvar ($doc->getElementsByTagName("params")) {
     foreach my $child ($paramvar->getChildNodes) {
        push(@paramarray, $child->getData);
     }
  }
 }


 if ($node->getNodeName() ne "root") {
      print $node->getNodeName. ", $title, @paramarray\n";
      @paramarray=();
 } 

 my @childNodes = $node->getChildNodes()
 if (@childNodes != null){
   my $numberChildNodes = $#childNodes + 1;
   my $loopIndex;
  for ($loopIndex =0; $loopIndex<$numberChildNodes; $loopIndex++) {
       ParseXML($childNodes[$loopIndex],$indent);
  }
 }
 }

  if ($type == TEXT_NODE) {
    my  $nodeText = $node->getNodeValue();
  }

 }
使用XML::DOM;
my$parser=newxml::DOM::parser;
my$doc=$parser->parsefile(“test.xml”);
my@paramarray=();
ParseXML($doc,“”);
子语法XML{
我的$node=$\u0];
我的$indent=$U1];
我的$title;
如果($node==null){
返回;
}
my$type=$node->getNodeType();
如果($type==文档\节点){
ParseXML($node->getFirstChild(),“”);
打破
}  
if($type==元素\节点){
$numberAttributes=0;
如果($node->getAttributes()!=null){
$numberAttributes=$node->getAttributes()->getLength();
}
对于($loopIndex=0;$loopIndexgetAttributes())->item($loopIndex);
如果($attribute->getNodeName()相等于“title”){
$title=$attribute->getNodeValue();
}
}
if($node->getNodeName()eq“params”){
foreach my$paramvar($doc->getElementsByTagName(“params”)){
foreach my$child($paramvar->getChildNodes){
推送(@paramarray,$child->getData);
}
}
}
如果($node->getNodeName()ne“root”){
打印$node->getNodeName.,$title,@paramarray\n”;
@参数数组=();
} 
my@childNodes=$node->getChildNodes()
if(@childNodes!=null){
my$numberChildNodes=$#childNodes+1;
我的$loopIndex;
对于($loopIndex=0;$loopIndexgetNodeValue();
}
}

首先,始终从

use strict;
use warnings;
这将捕获您可能犯的大量打字错误和愚蠢错误。您遇到的一个大问题是
null
不是Perl术语。Perl使用
undef
和函数(尽管在这种情况下,您可能不需要定义
,因为
undef
为false,而对象通常为true)

这里有一个稍微整理过的代码版本。它仍然不能产生您所要求的输出,但它更接近

use strict;
use warnings;
use XML::DOM;

my $parser = XML::DOM::Parser->new;
my $doc = $parser->parsefile("test.xml");
my @paramarray;
ParseXML($doc,"");

sub ParseXML {
  my $node = $_[0];
  my $indent = $_[1];
  my $title;

  if (not $node) {
    return;
  }

  my $type = $node->getNodeType();
  if ($type == DOCUMENT_NODE) {
    ParseXML($node->getFirstChild(),"");
    return;           
  }

  if ($type == ELEMENT_NODE) {
    my $numberAttributes =0;
    if ($node->getAttributes()) {
      $numberAttributes = $node->getAttributes()->getLength();
    }

    for (my $loopIndex =0; $loopIndex<$numberAttributes; $loopIndex++) {
      my $attribute = ($node->getAttributes())->item($loopIndex);
      if ($attribute->getNodeName() eq "title") {
        $title = $attribute->getNodeValue();
      }
    }

    if ($node->getNodeName() eq "params") {
      foreach my $paramvar ($doc->getElementsByTagName("params")) {
        foreach my $child ($paramvar->getChildNodes) {
          push(@paramarray, $child->getData);
        }
      }
    } elsif ($node->getNodeName() ne "root") {
      print $node->getNodeName. ", $title, @paramarray\n";
      @paramarray=();
    }

    my @childNodes = $node->getChildNodes(); # was missing semicolon

    if (@childNodes) {
      my $numberChildNodes = $#childNodes + 1;
      my $loopIndex;
      for ($loopIndex =0; $loopIndex<$numberChildNodes; $loopIndex++) {
        ParseXML($childNodes[$loopIndex],$indent);
      }
    }
  }

  if ($type == TEXT_NODE) {
    my $nodeText = $node->getNodeValue();
    # Were you planning on doing something here?
  }
}
使用严格;
使用警告;
使用XML::DOM;
my$parser=XML::DOM::parser->new;
my$doc=$parser->parsefile(“test.xml”);
我的@paramarray;
ParseXML($doc,“”);
子语法XML{
我的$node=$\u0];
我的$indent=$U1];
我的$title;
如果(不是$node){
返回;
}
my$type=$node->getNodeType();
如果($type==文档\节点){
ParseXML($node->getFirstChild(),“”);
返回;
}
if($type==元素\节点){
我的$numberAttributes=0;
如果($node->getAttributes()){
$numberAttributes=$node->getAttributes()->getLength();
}
对于(my$loopIndex=0;$loopIndexgetAttributes())->item($loopIndex);
如果($attribute->getNodeName()相等于“title”){
$title=$attribute->getNodeValue();
}
}
if($node->getNodeName()eq“params”){
foreach my$paramvar($doc->getElementsByTagName(“params”)){
foreach my$child($paramvar->getChildNodes){
推送(@paramarray,$child->getData);
}
}
}elsif($node->getNodeName()ne“root”){
打印$node->getNodeName.,$title,@paramarray\n”;
@参数数组=();
}
my@childNodes=$node->getChildNodes();#缺少分号
if(@childNodes){
my$numberChildNodes=$#childNodes+1;
我的$loopIndex;
对于($loopIndex=0;$loopIndexgetNodeValue();
#你打算在这里做点什么吗?
}
}

首先,始终从

use strict;
use warnings;
这将捕获您可能犯的大量打字错误和愚蠢错误。您遇到的一个大问题是
null
不是Perl术语。Perl使用
undef
和函数(尽管在这种情况下,您可能不需要定义
,因为
undef
为false,而对象通常为true)

这里有一个稍微整理过的代码版本。它仍然不能产生您所要求的输出,但它更接近

use strict;
use warnings;
use XML::DOM;

my $parser = XML::DOM::Parser->new;
my $doc = $parser->parsefile("test.xml");
my @paramarray;
ParseXML($doc,"");

sub ParseXML {
  my $node = $_[0];
  my $indent = $_[1];
  my $title;

  if (not $node) {
    return;
  }

  my $type = $node->getNodeType();
  if ($type == DOCUMENT_NODE) {
    ParseXML($node->getFirstChild(),"");
    return;           
  }

  if ($type == ELEMENT_NODE) {
    my $numberAttributes =0;
    if ($node->getAttributes()) {
      $numberAttributes = $node->getAttributes()->getLength();
    }

    for (my $loopIndex =0; $loopIndex<$numberAttributes; $loopIndex++) {
      my $attribute = ($node->getAttributes())->item($loopIndex);
      if ($attribute->getNodeName() eq "title") {
        $title = $attribute->getNodeValue();
      }
    }

    if ($node->getNodeName() eq "params") {
      foreach my $paramvar ($doc->getElementsByTagName("params")) {
        foreach my $child ($paramvar->getChildNodes) {
          push(@paramarray, $child->getData);
        }
      }
    } elsif ($node->getNodeName() ne "root") {
      print $node->getNodeName. ", $title, @paramarray\n";
      @paramarray=();
    }

    my @childNodes = $node->getChildNodes(); # was missing semicolon

    if (@childNodes) {
      my $numberChildNodes = $#childNodes + 1;
      my $loopIndex;
      for ($loopIndex =0; $loopIndex<$numberChildNodes; $loopIndex++) {
        ParseXML($childNodes[$loopIndex],$indent);
      }
    }
  }

  if ($type == TEXT_NODE) {
    my $nodeText = $node->getNodeValue();
    # Were you planning on doing something here?
  }
}
使用严格;
使用警告;
使用XML::DOM;
my$parser=XML::DOM::parser->new;
my$doc=$parser->parsefile(“test.xml”);
我的@paramarray;
ParseXML($doc,“”);
子语法XML{
我的$node=$\u0];
我的$indent=$U1];
我的$title;
如果(不是$node){
返回;
}
my$type=$node->getNodeType();
如果($type==文档\节点){
ParseXML($node->getFirstChild(),“”);
返回;
}
if($type==元素\节点){
我的$numberAttributes=0;
如果($node->getAttributes()){
$numberAttributes=$node->getAttributes()->getLength();
}
对于(my$loopIndex=0;$loopIndexgetAttributes())->item($loopIndex);
如果($attribute->getNodeName()相等于“title”){
$title=$attribute->getNodeValue();
}
}
if($node->getNodeName()eq“params”){
foreach my$paramvar($doc->getElementsByTagName(“params”)){
foreach my$child($paramvar->getChildNodes){
推送(@paramarray,$child->getData);
}
}
}elsif($node->getNodeName()ne“root”){
打印$node->getNodeName.,$title,@paramarray\n”;
@参数数组=();
}
my@childNodes=$node->getChildNodes();#缺少分号
if(@childNodes){
my$numberChildNodes=$#childNodes+1;
我的$loopIndex;
对于($loopIndex=0;$loopIndexgetNodeValue();
#你打算在这里做点什么吗?
}
}
我使用,因此这里有一个使用该模块的解决方案

use strict;
use warnings;

use XML::LibXML qw( );

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

for my $node ($root->findnodes('//*[@title]')) {
    my $name   = $node->nodeName();
    my $title  = $node->getAttribute('title');
    my @params = map $_->textContent, $node->findnodes('params');
    printf("%-10s %-11s %s\n", $name, $title, join(' ', @params));
}
更新:仍然是XML::LibXML,但这次没有使用XPath,以便于转换为XML::DOM

use strict;
use warnings;

use XML::LibXML qw( XML_ELEMENT_NODE );

sub find_params {
    my ($node) = @_;

    my @params;
    for my $child ($node->childNodes()) {
        next if $child->nodeType != XML_ELEMENT_NODE;
        next if $child->nodeName ne 'params';
        push @params, $child->textContent();        
    }

    return @params;    
}

sub visit {
    my ($node) = @_;
    return if $node->nodeType != XML_ELEMENT_NODE;

    if (my $title_node = $node->getAttributeNode('title')) {
        printf("%-10s %-11s %s\n",
            $node->nodeName(),
            $title_node->getValue(),
            join(' ', find_params($node)),
        );
    }

    visit($_) for $node->childNodes();
}

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

visit($root);
我使用,所以这里有一个使用该模块的解决方案

use strict;
use warnings;

use XML::LibXML qw( );

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

for my $node ($root->findnodes('//*[@title]')) {
    my $name   = $node->nodeName();
    my $title  = $node->getAttribute('title');
    my @params = map $_->textContent, $node->findnodes('params');
    printf("%-10s %-11s %s\n", $name, $title, join(' ', @params));
}
更新:仍然是XML::LibXML,但这次没有使用XPath,以便于转换为XML::DOM

use strict;
use warnings;

use XML::LibXML qw( XML_ELEMENT_NODE );

sub find_params {
    my ($node) = @_;

    my @params;
    for my $child ($node->childNodes()) {
        next if $child->nodeType != XML_ELEMENT_NODE;
        next if $child->nodeName ne 'params';
        push @params, $child->textContent();        
    }

    return @params;    
}

sub visit {
    my ($node) = @_;
    return if $node->nodeType != XML_ELEMENT_NODE;

    if (my $title_node = $node->getAttributeNode('title')) {
        printf("%-10s %-11s %s\n",
            $node->nodeName(),
            $title_node->getValue(),
            join(' ', find_params($node)),
        );
    }

    visit($_) for $node->childNodes();
}

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

visit($root);

以下是如何通过以下方式完成任务的示例代码:


以下是如何通过以下方式完成任务的示例代码:


请发布您迄今为止编写的代码,即使它工作不正常。请发布您迄今为止编写的代码,即使它工作不正常。使用XML:LibXML是我所需要的。非常感谢所有回复。建议的合作伙伴