# $Id: 06elements.t,v 1.1.1.2 2007/10/10 23:04:15 ahuda Exp $
##
# this test checks the DOM element and attribute interface of XML::LibXML
use Test;
BEGIN { plan tests => 187 };
use XML::LibXML;
my $foo = "foo";
my $bar = "bar";
my $nsURI = "http://foo";
my $prefix = "x";
my $attname1 = "A";
my $attvalue1 = "a";
my $attname2 = "B";
my $attvalue2 = "b";
my $attname3 = "C";
my @badnames= ("1A", "<><", "&", "-:");
print "# 1. bound node\n";
{
my $doc = XML::LibXML::Document->new();
my $elem = $doc->createElement( $foo );
ok($elem);
ok($elem->tagName, $foo);
{
foreach my $name ( @badnames ) {
eval { $elem->setNodeName( $name ); };
ok( $@ );
}
}
$elem->setAttribute( $attname1, $attvalue1 );
ok( $elem->hasAttribute($attname1) );
ok( $elem->getAttribute($attname1), $attvalue1);
my $attr = $elem->getAttributeNode($attname1);
ok($attr);
ok($attr->name, $attname1);
ok($attr->value, $attvalue1);
$elem->setAttribute( $attname1, $attvalue2 );
ok($elem->getAttribute($attname1), $attvalue2);
ok($attr->value, $attvalue2);
my $attr2 = $doc->createAttribute($attname2, $attvalue1);
ok($attr2);
$elem->setAttributeNode($attr2);
ok($elem->hasAttribute($attname2) );
ok($elem->getAttribute($attname2),$attvalue1);
my $tattr = $elem->getAttributeNode($attname2);
ok($tattr->isSameNode($attr2));
$elem->setAttribute($attname2, "");
ok($elem->hasAttribute($attname2) );
ok($elem->getAttribute($attname2), "");
$elem->setAttribute($attname3, "");
ok($elem->hasAttribute($attname3) );
ok($elem->getAttribute($attname3), "");
{
foreach my $name ( @badnames ) {
eval {$elem->setAttribute( $name, "X" );};
ok( $@ );
}
}
print "# 1.1 Namespaced Attributes\n";
$elem->setAttributeNS( $nsURI, $prefix . ":". $foo, $attvalue2 );
ok( $elem->hasAttributeNS( $nsURI, $foo ) );
ok( ! $elem->hasAttribute( $foo ) );
ok( $elem->hasAttribute( $prefix.":".$foo ) );
# warn $elem->toString() , "\n";
$tattr = $elem->getAttributeNodeNS( $nsURI, $foo );
ok($tattr);
ok($tattr->name, $foo);
ok($tattr->nodeName, $prefix .":".$foo);
ok($tattr->value, $attvalue2 );
$elem->removeAttributeNode( $tattr );
ok( !$elem->hasAttributeNS($nsURI, $foo) );
# empty NS
$elem->setAttributeNS( '', $foo, $attvalue2 );
ok( $elem->hasAttribute( $foo ) );
$tattr = $elem->getAttributeNode( $foo );
ok($tattr);
ok($tattr->name, $foo);
ok($tattr->nodeName, $foo);
ok(!defined($tattr->namespaceURI));
ok($tattr->value, $attvalue2 );
ok($elem->hasAttribute($foo) == 1);
ok($elem->hasAttributeNS(undef, $foo) == 1);
ok($elem->hasAttributeNS('', $foo) == 1);
$elem->removeAttributeNode( $tattr );
ok( !$elem->hasAttributeNS('', $foo) );
ok( !$elem->hasAttributeNS(undef, $foo) );
# node based functions
my $e2 = $doc->createElement($foo);
$doc->setDocumentElement($e2);
my $nsAttr = $doc->createAttributeNS( $nsURI.".x", $prefix . ":". $foo, $bar);
ok( $nsAttr );
$elem->setAttributeNodeNS($nsAttr);
ok( $elem->hasAttributeNS($nsURI.".x", $foo) );
$elem->removeAttributeNS( $nsURI.".x", $foo);
ok( !$elem->hasAttributeNS($nsURI.".x", $foo) );
# warn $elem->toString;
print "# set attribute ".$prefix . ":". $attname1."\n";
$elem->setAttributeNS( $nsURI, $prefix . ":". $attname1, $attvalue2 );
# warn $elem->toString;
$elem->removeAttributeNS("",$attname1);
# warn $elem->toString;
ok( ! $elem->hasAttribute($attname1) );
ok( $elem->hasAttributeNS($nsURI,$attname1) );
# warn $elem->toString;
{
foreach my $name ( @badnames ) {
eval {$elem->setAttributeNS( undef, $name, "X" );};
ok( $@ );
}
}
}
print "# 2. unbound node\n";
{
my $elem = XML::LibXML::Element->new($foo);
ok($elem);
ok($elem->tagName, $foo);
$elem->setAttribute( $attname1, $attvalue1 );
ok( $elem->hasAttribute($attname1) );
ok( $elem->getAttribute($attname1), $attvalue1);
my $attr = $elem->getAttributeNode($attname1);
ok($attr);
ok($attr->name, $attname1);
ok($attr->value, $attvalue1);
$elem->setAttributeNS( $nsURI, $prefix . ":". $foo, $attvalue2 );
ok( $elem->hasAttributeNS( $nsURI, $foo ) );
# warn $elem->toString() , "\n";
my $tattr = $elem->getAttributeNodeNS( $nsURI, $foo );
ok($tattr);
ok($tattr->name, $foo);
ok($tattr->nodeName, $prefix .":".$foo);
ok($tattr->value, $attvalue2 );
$elem->removeAttributeNode( $tattr );
ok( !$elem->hasAttributeNS($nsURI, $foo) );
# warn $elem->toString() , "\n";
}
print "# 3. Namespace handling\n";
print "# 3.1 Namespace switching\n";
{
my $elem = XML::LibXML::Element->new($foo);
ok($elem);
my $doc = XML::LibXML::Document->new();
my $e2 = $doc->createElement($foo);
$doc->setDocumentElement($e2);
my $nsAttr = $doc->createAttributeNS( $nsURI, $prefix . ":". $foo, $bar);
ok( $nsAttr );
$elem->setAttributeNodeNS($nsAttr);
ok( $elem->hasAttributeNS($nsURI, $foo) );
ok( not defined $nsAttr->ownerDocument);
# warn $elem->toString() , "\n";
}
print "# 3.2 default Namespace and Attributes\n";
{
my $doc = XML::LibXML::Document->new();
my $elem = $doc->createElementNS( "foo", "root" );
$doc->setDocumentElement( $elem );
$elem->setNamespace( "foo", "bar" );
$elem->setAttributeNS( "foo", "x:attr", "test" );
$elem->setAttributeNS( undef, "attr2", "test" );
ok( $elem->getAttributeNS( "foo", "attr" ), "test" );
ok( $elem->getAttributeNS( "", "attr2" ), "test" );
# warn $doc->toString;
# actually this doesn't work correctly with libxml2 <= 2.4.23
$elem->setAttributeNS( "foo", "attr2", "bar" );
ok( $elem->getAttributeNS( "foo", "attr2" ), "bar" );
# warn $doc->toString;
}
print "# 4. Text Append and Normalization\n";
{
my $doc = XML::LibXML::Document->new();
my $t1 = $doc->createTextNode( "bar1" );
my $t2 = $doc->createTextNode( "bar2" );
my $t3 = $doc->createTextNode( "bar3" );
my $e = $doc->createElement("foo");
$e->appendChild( $t1 );
$e->appendChild( $t2 );
$e->appendChild( $t3 );
my @cn = $e->childNodes;
# this is the correct behaviour for DOM. the nodes are still
# refered
ok( scalar( @cn ), 3 );
$e->normalize;
@cn = $e->childNodes;
ok( scalar( @cn ), 1 );
ok(not defined $t2->parentNode);
ok(not defined $t3->parentNode);
}
print "# 5. XML::LibXML extensions\n";
{
my $plainstring = "foo";
my $stdentstring= "$foo & this";
my $doc = XML::LibXML::Document->new();
my $elem = $doc->createElement( $foo );
$doc->setDocumentElement( $elem );
$elem->appendText( $plainstring );
ok( $elem->string_value , $plainstring );
$elem->appendText( $stdentstring );
ok( $elem->string_value , $plainstring.$stdentstring );
$elem->appendTextChild( "foo");
$elem->appendTextChild( "foo" => "foo&bar" );
my @cn = $elem->childNodes;
ok( @cn );
ok( scalar(@cn), 3 );
ok( !$cn[1]->hasChildNodes);
ok( $cn[2]->hasChildNodes);
}
print "# 6. XML::LibXML::Attr nodes\n";
{
my $dtd = <<'EOF';
]>
EOF
my $ns = q(urn:xx);
my $xml_nons = qq();
my $xml_ns = qq();
for my $xml ($xml_nons, $xml_ns) {
my $parser = new XML::LibXML;
$parser->complete_attributes(0);
$parser->expand_entities(0);
my $doc = $parser->parse_string($dtd.$xml);
ok ($doc);
my $root = $doc->getDocumentElement;
{
my $attr = $root->getAttributeNode('foo');
ok ($attr);
ok (ref($attr), 'XML::LibXML::Attr');
ok ($root->isSameNode($attr->ownerElement));
ok ($attr->value, '"barENT"');
ok ($attr->serializeContent, '"bar&ent;"');
ok ($attr->toString, ' foo=""bar&ent;""');
}
{
my $attr = $root->getAttributeNodeNS(undef,'foo');
ok ($attr);
ok (ref($attr), 'XML::LibXML::Attr');
ok ($root->isSameNode($attr->ownerElement));
ok ($attr->value, '"barENT"');
}
# fixed values are defined
ok ($root->getAttribute('fixed'),'foo');
skip (
XML::LibXML::LIBXML_VERSION >= 20627 ? 0 : 'skipping for libxml2 <= 2.6.27',
$root->getAttributeNS($ns,'ns_fixed'),'ns_foo');
ok ($root->getAttribute('a:ns_fixed'),'ns_foo');
ok ($root->hasAttribute('fixed'),0);
ok ($root->hasAttributeNS($ns,'ns_fixed'),0);
ok ($root->hasAttribute('a:ns_fixed'),0);
# but no attribute nodes correspond to them
ok (!defined $root->getAttributeNode('a:ns_fixed'));
ok (!defined $root->getAttributeNode('fixed'));
ok (!defined $root->getAttributeNode('name'));
ok (!defined $root->getAttributeNode('baz'));
ok (!defined $root->getAttributeNodeNS($ns,'foo'));
ok (!defined $root->getAttributeNodeNS($ns,'fixed'));
ok (!defined $root->getAttributeNodeNS($ns,'ns_fixed'));
ok (!defined $root->getAttributeNodeNS(undef,'fixed'));
ok (!defined $root->getAttributeNodeNS(undef,'name'));
ok (!defined $root->getAttributeNodeNS(undef,'baz'));
}
for my $xml ($xml_nons, $xml_ns) {
my $parser = new XML::LibXML;
$parser->complete_attributes(1);
$parser->expand_entities(1);
my $doc = $parser->parse_string($dtd.$xml);
ok ($doc);
my $root = $doc->getDocumentElement;
{
my $attr = $root->getAttributeNode('foo');
ok ($attr);
ok (ref($attr), 'XML::LibXML::Attr');
ok ($root->isSameNode($attr->ownerElement));
ok ($attr->value, '"barENT"');
ok ($attr->serializeContent, '"barENT"');
ok ($attr->toString, ' foo=""barENT""');
}
# fixed values are defined
ok ($root->getAttribute('fixed'),'foo');
ok ($root->getAttributeNS($ns,'ns_fixed'),'ns_foo');
ok ($root->getAttribute('a:ns_fixed'),'ns_foo');
# and attribute nodes are created
{
my $attr = $root->getAttributeNode('fixed');
ok (ref($attr), 'XML::LibXML::Attr');
ok ($attr->value,'foo');
ok ($attr->toString, ' fixed="foo"');
}
{
my $attr = $root->getAttributeNode('a:ns_fixed');
ok (ref($attr), 'XML::LibXML::Attr');
ok ($attr->value,'ns_foo');
}
{
my $attr = $root->getAttributeNodeNS($ns,'ns_fixed');
ok (ref($attr), 'XML::LibXML::Attr');
ok ($attr->value,'ns_foo');
ok ($attr->toString, ' a:ns_fixed="ns_foo"');
}
ok (!defined $root->getAttributeNode('ns_fixed'));
ok (!defined $root->getAttributeNode('name'));
ok (!defined $root->getAttributeNode('baz'));
ok (!defined $root->getAttributeNodeNS($ns,'foo'));
ok (!defined $root->getAttributeNodeNS($ns,'fixed'));
ok (!defined $root->getAttributeNodeNS(undef,'name'));
ok (!defined $root->getAttributeNodeNS(undef,'baz'));
}
}