今天翻到以前写的一段程序,决定改变文本方式为xml方式描述增强可读性。不想碰到了一个问题折腾了几个小时。
一 网络安装xml 模块
ActivePerl-5.8.8.819-MSWin32-x86-267479.msi安装后的路径c:\perl 加入环境变量
ppm install XML::Writer
ppm install XML::DOM
二 编写XML文件scenarios.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
loadrunner scenario drive events
-->
<scenarios>
<scenario name="test1">
<loadrunnerscenario>
<path>f:\1.lrs</path>
<resultlocation></resultlocation>
</loadrunnerscenario>
</scenario>
<scenario name="test2">
<loadrunnerscenario>
<path>f:\2.lrs</path>
<resultlocation></resultlocation>
</loadrunnerscenario>
</scenario>
</scenarios>
三 编程获取 path元素的值
第一次写的程序
use XML::DOM;
XML::DOM::Element;
my $parser = new XML::DOM::Parser;
my $doc = $parser->parsefile ("scenarios.xml");
my $nodes = $doc->getElementsByTagName ("loadrunnerscenario");
my $n = $nodes->getLength;
for (my $i = 0; $i < $n; $i++)
{
my $node = $nodes->item ($i);
#print "value=" . $node->toString() . "\n";
my $subNodes= $node->getElementsByTagName("path");
my $subel =$subNodes->item(0);
print "nodetype=". $subel->getNodeTypeName . ",value=". $subel->getNodeValue();
}
# Print doc file
#$doc->printToFile ("out.xml");
# Print to string
#print $doc->toString;
# Avoid memory leaks - cleanup circular references for garbage collection
$doc->dispose;
执行导致
C:\Perl\bin>perl part2.pl
nodetype=ELEMENT_NODE,value=
不明白为何getNodeValue=空值?
再看上下文:
getNodeValue and setNodeValue (value)
Returns a string or undef, depending on the node type. This method is provided for completeness. In other languages it saves the programmer an upcast. The value is either available thru some other method defined in the subclass, or else undef is returned. Here are the corresponding methods: Attr::getValue, Text::getData, CDATASection::getData, Comment::getData, ProcessingInstruction::getData.
似乎也没有错误。到底问题在哪里?
没有很好的办法,google 到http://www.ibm.com/developerworks/library/xml-perl2/?S_TACT=105AGX52&S_CMP=cn-a-x
改写如下,得以解决。问题的关键在于:($node->getNodeType() == TEXT_NODE 才能获取到element的值
use XML::DOM;
XML::DOM::Element;
sub traverse($)
{
my($node)= @_;
if ($node->getNodeType == ELEMENT_NODE)
{
foreach my $child ($node->getChildNodes())
{
return traverse($child);
}
}
elsif ($node->getNodeType() == TEXT_NODE)
{
#print $node->getData . "\n";
$data=$node->getData;
return $data;
}
}
my $parser = new XML::DOM::Parser;
my $doc = $parser->parsefile ("scenarios.xml");
my $nodes = $doc->getElementsByTagName ("loadrunnerscenario");
my $n = $nodes->getLength;
for (my $i = 0; $i < $n; $i++)
{
my $node = $nodes->item ($i);
#print "value=" . $node->toString() . "\n";
my $subNodes= $node->getElementsByTagName("path");
my $subel =$subNodes->item(0);
#print "nodetype=". $subel->getNodeTypeName . ",value=". $subel->getNodeValue() . "\n";
my $rv=&traverse($subel);
print $rv ."\n";
if ($subel->getNodeType == ELEMENT_NODE)
{
print "nodetype=". $subel->getChildNodes()->item(0)->getNodeTypeName. ",nodevalue=". $subel->getChildNodes()->item(0)->getNodeValue(). "\n";
}
}
# Print doc file
#$doc->printToFile ("out.xml");
# Print to string
#print $doc->toString;
# Avoid memory leaks - cleanup circular references for garbage collection
$doc->dispose;