Chris Cheung
2003-11-11 05:54:25 UTC
Dear all,
Very often I need to clone a DOM subtree to a new DOMDocument and make
the root of the subtree be the document element of the new DOMDocument.
However, it seems that in Xerces-C++/Perl, the document element is
created when creating the DOMDocument (via
DomImplementation::createDocument) and cannot be replaced afterward.
Hence I cannot use the DOMDocument::importNode to directly deep clone the
root node of the source subtree, but rather I have to copy its
attributes and child nodes one by one (in Perl code):
sub element2Doc
{
my ($element) = @_;
# Create a new DOM Document
my $domImpl =
XML::Xerces::DOMImplementationRegistry::getDOMImplementation('LS')
my $newDoc = $domImpl->createDocument($element->getNamespaceURI,
$element->getTagName, undef);
# Need to copy every attribute and every child node,
# (Since these is no API to set document element of a DOMDocument.)
my $newRoot = $newDoc->getDocumentElement();
my $attrs = $element->getAttributes();
for (my $i = 0; $i < $attrs->getLength; $i++)
{
my $attr = $attrs->item($i);
my $nsURI = $attr->getNamespaceURI;
if ($nsURI)
{
# The attribute is qualified
$newRoot->setAttributeNS($nsURI, $attr->getName,
$attr->getValue);
}
else
{
$newRoot->setAttribute($attr->getName, $attr->getValue);
}
}
my @childNodes = $element->getChildNodes();
foreach (@childNodes)
{
my $copiedChild = $newDoc->importNode($_, 1);
$newRoot->appendChild($copiedChild);
}
return $newDoc;
}
Using the Xerces-Perl wrapper over the efficient Xerces-C++ library,
the code runs slowly since a lot of Perl statements are executed each
calls short C++ methods, especially for broad but not deep source DOM
subtree.
Is there any smarter way to do the same thing?
Thank you in advance for any help.
Very often I need to clone a DOM subtree to a new DOMDocument and make
the root of the subtree be the document element of the new DOMDocument.
However, it seems that in Xerces-C++/Perl, the document element is
created when creating the DOMDocument (via
DomImplementation::createDocument) and cannot be replaced afterward.
Hence I cannot use the DOMDocument::importNode to directly deep clone the
root node of the source subtree, but rather I have to copy its
attributes and child nodes one by one (in Perl code):
sub element2Doc
{
my ($element) = @_;
# Create a new DOM Document
my $domImpl =
XML::Xerces::DOMImplementationRegistry::getDOMImplementation('LS')
my $newDoc = $domImpl->createDocument($element->getNamespaceURI,
$element->getTagName, undef);
# Need to copy every attribute and every child node,
# (Since these is no API to set document element of a DOMDocument.)
my $newRoot = $newDoc->getDocumentElement();
my $attrs = $element->getAttributes();
for (my $i = 0; $i < $attrs->getLength; $i++)
{
my $attr = $attrs->item($i);
my $nsURI = $attr->getNamespaceURI;
if ($nsURI)
{
# The attribute is qualified
$newRoot->setAttributeNS($nsURI, $attr->getName,
$attr->getValue);
}
else
{
$newRoot->setAttribute($attr->getName, $attr->getValue);
}
}
my @childNodes = $element->getChildNodes();
foreach (@childNodes)
{
my $copiedChild = $newDoc->importNode($_, 1);
$newRoot->appendChild($copiedChild);
}
return $newDoc;
}
Using the Xerces-Perl wrapper over the efficient Xerces-C++ library,
the code runs slowly since a lot of Perl statements are executed each
calls short C++ methods, especially for broad but not deep source DOM
subtree.
Is there any smarter way to do the same thing?
Thank you in advance for any help.
--
Best Regards,
Chris Cheung
Center for Large-Scale Computation
Have a nice day!
Best Regards,
Chris Cheung
Center for Large-Scale Computation
Have a nice day!