Esempio n. 1
0
/*================================================================
*   ixmlNode_cloneNodeTree
*       clones a node tree.
*       Internal to parser only.
*
*=================================================================*/
IXML_Node *
ixmlNode_cloneNodeTree( IN IXML_Node * nodeptr,
                        IN BOOL deep )
{
    IXML_Node *newNode = NULL;
    IXML_Element *newElement;
    IXML_Node *childNode;

    assert( nodeptr != NULL );

    switch ( nodeptr->nodeType ) {
    case eELEMENT_NODE:
        newElement =
            ixmlNode_cloneElement( ( IXML_Element * ) nodeptr );
        newElement->n.firstAttr =
            ixmlNode_cloneNodeTreeRecursive( nodeptr->firstAttr,
                                             deep );
        if( deep ) {
            newElement->n.firstChild =
                ixmlNode_cloneNodeTreeRecursive( nodeptr->firstChild,
                                                 deep );
            childNode = newElement->n.firstChild;
            while( childNode != NULL ) {
                childNode->parentNode = ( IXML_Node * ) newElement;
                childNode = childNode->nextSibling;
            }
            newElement->n.nextSibling = NULL;
        }

        newNode = ( IXML_Node * ) newElement;
        break;

    case eATTRIBUTE_NODE:
    case eTEXT_NODE:
    case eCDATA_SECTION_NODE:
    case eDOCUMENT_NODE:
        newNode = ixmlNode_cloneNodeTreeRecursive( nodeptr, deep );
        break;

    case eINVALID_NODE:
    case eENTITY_REFERENCE_NODE:
    case eENTITY_NODE:
    case ePROCESSING_INSTRUCTION_NODE:
    case eCOMMENT_NODE:
    case eDOCUMENT_TYPE_NODE:
    case eDOCUMENT_FRAGMENT_NODE:
    case eNOTATION_NODE:
        /* create a new node here?            newNode = (IXML_Node *)malloc(sizeof(IXML_Node));
                    if( newNode == NULL ) {
                        return NULL;
                    }*/
        break;
    }

    // by spec, the duplicate node has no parent
    newNode->parentNode = NULL;

    return newNode;
}
/*================================================================
*   ixmlNode_cloneNodeTreeRecursive
*       recursive functions that clones node tree of nodeptr.
*       Internal to parser only.
*       
*=================================================================*/
IXML_Node *
ixmlNode_cloneNodeTreeRecursive( IN IXML_Node * nodeptr,
                                 IN BOOL deep )
{
    IXML_Node *newNode = NULL;
    IXML_Element *newElement;
    IXML_Attr *newAttr = NULL;
    IXML_CDATASection *newCDATA = NULL;
    IXML_Document *newDoc;
    IXML_Node *nextSib;

    if( nodeptr != NULL ) {
        switch ( nodeptr->nodeType ) {
            case eELEMENT_NODE:
                newElement =
                    ixmlNode_cloneElement( ( IXML_Element * ) nodeptr );
                newElement->n.firstAttr =
                    ixmlNode_cloneNodeTreeRecursive( nodeptr->firstAttr,
                                                     deep );
                if( deep ) {
                    newElement->n.firstChild =
                        ixmlNode_cloneNodeTreeRecursive( nodeptr->
                                                         firstChild,
                                                         deep );
                    if( newElement->n.firstChild != NULL ) {
                        ( newElement->n.firstChild )->parentNode =
                            ( IXML_Node * ) newElement;
                        ixmlNode_setSiblingNodesParent( newElement->n.
                                                        firstChild );
                    }
                    nextSib =
                        ixmlNode_cloneNodeTreeRecursive( nodeptr->
                                                         nextSibling,
                                                         deep );
                    newElement->n.nextSibling = nextSib;
                    if( nextSib != NULL ) {
                        nextSib->prevSibling = ( IXML_Node * ) newElement;
                    }
                }

                newNode = ( IXML_Node * ) newElement;
                break;

            case eATTRIBUTE_NODE:
                newAttr = ixmlNode_cloneAttr( ( IXML_Attr * ) nodeptr );
                nextSib =
                    ixmlNode_cloneNodeTreeRecursive( nodeptr->nextSibling,
                                                     deep );
                newAttr->n.nextSibling = nextSib;

                if( nextSib != NULL ) {
                    nextSib->prevSibling = ( IXML_Node * ) newAttr;
                }
                newNode = ( IXML_Node * ) newAttr;
                break;

            case eTEXT_NODE:
                newNode = ixmlNode_cloneTextNode( nodeptr );
                break;

            case eCDATA_SECTION_NODE:
                newCDATA =
                    ixmlNode_cloneCDATASect( ( IXML_CDATASection * )
                                             nodeptr );
                newNode = ( IXML_Node * ) newCDATA;
                break;

            case eDOCUMENT_NODE:
                newDoc = ixmlNode_cloneDoc( ( IXML_Document * ) nodeptr );
                newNode = ( IXML_Node * ) newDoc;
                if( deep ) {
                    newNode->firstChild =
                        ixmlNode_cloneNodeTreeRecursive( nodeptr->
                                                         firstChild,
                                                         deep );
                    if( newNode->firstChild != NULL ) {
                        newNode->firstChild->parentNode = newNode;
                    }
                }

                break;

            case eINVALID_NODE:
            case eENTITY_REFERENCE_NODE:
            case eENTITY_NODE:
            case ePROCESSING_INSTRUCTION_NODE:
            case eCOMMENT_NODE:
            case eDOCUMENT_TYPE_NODE:
            case eDOCUMENT_FRAGMENT_NODE:
            case eNOTATION_NODE:
                break;
        }
    }

    return newNode;
}