我尝试修改一些使用XML::LibXML
使用XML::DOM
的代码,因为前者在我的fatcow服务器上不可用。
如何设置XML::DOM::Document
对象的根文档? setDocumentElement
中没有XML::DOM::Document
方法。
以下是有问题的代码(来自XML::XML2JSON
),我想知道如何更换标有星号的代码。
=head2 obj2dom
Takes a perl data structure as input. (Must be a hashref.)
Returns an XML::DOM::Document object. #JMO
This method expects the object to be in the same format as
would be returned by the xml2obj method.
=cut
sub obj2dom
{
my ( $Self, $Obj ) = @_;
croak "Object must be a hashref" unless ref($Obj) eq 'HASH';
my $Version = $Obj->{ $Self->{attribute_prefix} . 'version' } || $Obj->{'version'} || '1.0';
my $Encoding = $Obj->{ $Self->{attribute_prefix} . 'encoding' } || $Obj->{'encoding'} || 'UTF-8';
#my $Dom = $XMLPARSER->createDocument( $Version, $Encoding ); #JMO
my $Dom = XML::DOM::Document->new(); #JMO
$Dom->setXMLDecl($Dom->createXMLDecl($Version, $Encoding)); #JMO
my $GotRoot = 0;
#delete @$Obj{ grep { /^$Self->{attribute_prefix}/ } keys %$Obj };
foreach my $Key ( keys %$Obj )
{
$Obj->{$Key} = "" unless defined($Obj->{$Key});
my $RefType = ref( $Obj->{$Key} );
warn "Value ref type for $Key is: $RefType (value seems to be $Obj->{$Key})" if $Self->{debug};
my $Name = $Key;
# replace a "$" in the name with a ":"
$Name =~ s/([^^])\$/$1\:/;
if ( $RefType eq 'HASH' )
{
warn "Creating root element: $Name" if $Self->{debug};
croak "You may only have one root element: $Key" if $GotRoot;
$GotRoot = 1;
my $Root = $Dom->createElement($Name);
$Dom->setDocumentElement($Root); # **********
$Self->_process_element_hash( $Dom, $Root, $Obj->{$Key} );
}
elsif ( $RefType eq 'ARRAY' )
{
croak "You cant have an array of root nodes: $Key";
}
elsif ( !$RefType )
{
if ( $Obj->{$Key} ne '' )
{
unless ($GotRoot)
{
my $Root;
eval { $Root = $Dom->createElement($Name) };
if ( $@ ) {
die "Problem creating root element $Name: $@";
}
$Dom->setDocumentElement($Root); # **********
$Root->appendText( $Obj->{$Key} );
$GotRoot = 1;
}
}
else
{
croak "Invalid data for key: $Key";
}
}
else
{
warn "unknown reference: $RefType";
}
}
return $Dom;
}
答案 0 :(得分:2)
XML::DOM::Document
对象代表文档根或文档实体。请注意,它与根元素之间存在区别,根元素是文档根目录的唯一子元素,也是XML文档的最外层元素。
获得XML::DOM::Document
个对象后,使用appendChild
添加到其中的第一个子项将成为根元素。如果您尝试附加元素节点以外的任何内容,则会出现错误
XML::DOM::DOMException(Code=3, Name=HIERARCHY_REQUEST_ERR, Message=bad node type)
或者如果您尝试添加多个节点,您将看到
XML::DOM::DOMException(Code=3, Name=HIERARCHY_REQUEST_ERR, Message=document can have only one Element)
换句话说,与setDocumentElement
最接近的等价物只是appendChild
,就像这样
my $Root = $Dom->createElement($Name);
$Dom->appendChild($Root);
这是一个构建完整XML文档树的示例程序。它会将一个带有标记root
的元素附加到文档对象,然后创建两个带有标记child1
和child2
的子元素,为每个元素添加一些文本,然后将它们附加到根元素。
use strict;
use 5.010;
use warnings;
use XML::DOM;
my $dom = XML::DOM::Document->new;
$dom->setXMLDecl($dom->createXMLDecl(qw/ 1.0 UTF-8 /));
my $root = $dom->createElement('root');
$dom->appendChild($root);
for my $tag (qw/ child1 child2 /) {
my $child = $dom->createElement($tag);
$root->appendChild($child);
my $text = $dom->createTextNode("Text for $tag");
$child->appendChild($text);
}
print $dom->toString;
<强>输出强>
<?xml version="1.0" encoding="UTF-8"?>
<root><child1>Text for child1</child1><child2>Text for child2</child2></root>
最后一点。标识符中的大写字母通常保留给全局变量,例如Package::Names
。词法范围的变量应该使用小写字母数字和下划线标识符。但是,在这种情况下,我意识到XML::XML2JSON
模块本身违反了这条规则!