使用perl解析xml文档的元素(includng属性)和文本节点
我有以下test.xml文件:使用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"> <
<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是我所需要的。非常感谢所有回复。建议的合作伙伴