You are viewing a plain text version of this content. The canonical link for it is here.
Posted to p-dev@xerces.apache.org by Chris Cheung <ch...@clc.cuhk.edu.hk> on 2003/11/11 06:54:25 UTC

Clone a DOM subtree to the root of a new DOMDocument efficiently ?

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.

-- 
Best Regards,

Chris Cheung
Center for Large-Scale Computation

Have a nice day!



---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-p-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-p-dev-help@xml.apache.org


RE: Clone a DOM subtree to the root of a new DOMDocument efficiently ?

Posted by Chris Cheung <ch...@clc.cuhk.edu.hk>.
Dear Erik,

  That exactly solved my problem. Thank you very much!

On Tue, 11 Nov 2003, Erik Rydgren wrote:

> Well I have no problems replacing a document root with the 2.2.0
> codebase. I use the following code. The code is pure DOM so no extra
> fancy stuff, don't mind the wrapper classes.
> 
> cDocument* poDoc1 = GetDOMImplementation().CreateDocument("", "test",
> NULL);
> cDocument* poDoc2 = GetDOMImplementation().CreateDocument("", "test2",
> NULL);
> poDoc2->GetDocumentElement()->AppendChild(poDoc2->CreateElement("elem1")
> ->cast());
> poDoc2->GetDocumentElement()->AppendChild(poDoc2->CreateElement("elem2")
> ->cast());
> poDoc2->GetDocumentElement()->AppendChild(poDoc2->CreateElement("elem3")
> ->cast());
> 
> cNode* poClone =
> poDoc1->ImportNode(poDoc2->GetDocumentElement()->cast(), true);
> poDoc1->ReplaceChild(poClone, poDoc1->GetDocumentElement()->cast());
> 
> // HERE the document root of poDoc1 is test2 with 3 children
> 
> Best regards
> / Erik
> 
> > -----Original Message-----
> > From: Chris Cheung [mailto:cheungcc@clc.cuhk.edu.hk]
> > Sent: den 11 november 2003 06:54
> > To: xerces-c-dev@xml.apache.org; xerces-p-dev@xml.apache.org
> > Cc: Anthony Chan
> > Subject: Clone a DOM subtree to the root of a new DOMDocument
> efficiently
> > ?
> > 
> > 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):
> > 

-- 
Best Regards,

Chris Cheung
Center for Large-Scale Computation

Have a nice day!


---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org


RE: Clone a DOM subtree to the root of a new DOMDocument efficiently ?

Posted by Erik Rydgren <er...@mandarinen.se>.
Well I have no problems replacing a document root with the 2.2.0
codebase. I use the following code. The code is pure DOM so no extra
fancy stuff, don't mind the wrapper classes.

cDocument* poDoc1 = GetDOMImplementation().CreateDocument("", "test",
NULL);
cDocument* poDoc2 = GetDOMImplementation().CreateDocument("", "test2",
NULL);
poDoc2->GetDocumentElement()->AppendChild(poDoc2->CreateElement("elem1")
->cast());
poDoc2->GetDocumentElement()->AppendChild(poDoc2->CreateElement("elem2")
->cast());
poDoc2->GetDocumentElement()->AppendChild(poDoc2->CreateElement("elem3")
->cast());

cNode* poClone =
poDoc1->ImportNode(poDoc2->GetDocumentElement()->cast(), true);
poDoc1->ReplaceChild(poClone, poDoc1->GetDocumentElement()->cast());

// HERE the document root of poDoc1 is test2 with 3 children

Best regards
/ Erik

> -----Original Message-----
> From: Chris Cheung [mailto:cheungcc@clc.cuhk.edu.hk]
> Sent: den 11 november 2003 06:54
> To: xerces-c-dev@xml.apache.org; xerces-p-dev@xml.apache.org
> Cc: Anthony Chan
> Subject: Clone a DOM subtree to the root of a new DOMDocument
efficiently
> ?
> 
> 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.
> 
> --
> Best Regards,
> 
> Chris Cheung
> Center for Large-Scale Computation
> 
> Have a nice day!
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
> For additional commands, e-mail: xerces-c-dev-help@xml.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-c-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-c-dev-help@xml.apache.org