Link to home
Start Free TrialLog in
Avatar of david_johns
david_johns

asked on

IXMLDOMDocument::insertBefore()

I am using MSXML to generate an XML document.  I use the loadXML method to generate the DOCTYPE node and then need to add the processing instruction above the DocType.  I am trying to use insertBefore to do it, but can't seem to get the refChild argument right.  Could someone give me a hand?  I guess I am not sure in what format the pointer to the IXMLDOMNode is supposed to be assigned to a VARIANT.  This was my best guess, but it always fails at the insertBefore call.  Below is the code:

.
.
.
    //Create DocType Reference
    hr = pDoc->loadXML(L"<!DOCTYPE Test SYSTEM \"Test.dtd\">\n<Test></Test>", &varResult);
    if(hr!=S_OK || varResult!=VARIANT_TRUE){
        if(pDoc->get_parseError(&pXMLErr)==S_OK){
            if(node.Import(pXMLErr)){
                strError.Format("Unable to build XML file.  %s.", node.text);
                throw strError;
            }
            pXMLErr->Release();
            pXMLErr=NULL;
        }
        strError = "Unable to build XML file.  The file may be reserved by the operating system.";
        throw strError;
    }

    if(pDoc->get_childNodes(&pNodes)!=S_OK){
        strError = "Unable to create root element.";
        throw strError;
    }

    //Create Processing Instruction
    if(pNodes->get_item(0, &pDocType)!=S_OK){
        strError = "Unable to create root element.";
        throw strError;
    }
    VariantInit(&varRefChild);
    varRefChild.vt = VT_UI4;
    varRefChild.uiVal = (unsigned int) pDocType;
    if(pDoc->createProcessingInstruction(L"xml", L"version=\"1.0\" encoding=\"UTF-8\"", &pProcessInstruction)!=S_OK){
        strError = "Unable to create xml processing instruction.";
        throw strError;
    }
    if(pDoc->insertBefore(pProcessInstruction, varRefChild, &pNode)!=S_OK){
        strError = "Unable to add xml processing instruction.";
        throw strError;
    }
    pDocType.Release();
    pNode.Release();
    pProcessInstruction.Release();
.
.
.

Thanks,
David Johns
Avatar of andrewjb
andrewjb
Flag of United Kingdom of Great Britain and Northern Ireland image

Don't use variants, just use an IXMLDOMNode, which is an interface pointer.

Avatar of david_johns
david_johns

ASKER

andrewjb,

I don't understand what you mean.  I try:

    if(pDoc->insertBefore(pProcessInstruction, pDocType, &pNode)!=S_OK){

where pDocType is defined as MSXML2::IXMLDOMNodePtr pDocType=NULL,

and I get:

error C2664: 'insertBefore' : cannot convert parameter 2 from 'class _com_ptr_t<class _com_IIID<struct MSXML2::IXMLDOMNode,&struct __s_GUID
 _GUID_2933bf80_7b36_11d2_b20e_00c04f983e60> >' to 'struct tagVARIANT'

I tried using &pDocType and *pDocType as well.  Could you explain what you mean?

Thanks,
David
Got it...:

    //Create Processing Instruction
    if(pNodes->get_item(0, &pDocType)!=S_OK){
        strError = "Unable to create root element.";
        throw strError;
    }
    varRefChild.vt = VT_UKNOWN;
    varRefChild.punkVal= (IUnknown*) pDocType;
    if(pDoc->createProcessingInstruction(L"xml", L"version=\"1.0\" encoding=\"UTF-8\"", &pProcessInstruction)!=S_OK){
        strError = "Unable to create xml processing instruction.";
        throw strError;
    }
    if(pDoc->insertBefore(pProcessInstruction, varRefChild, &pNode)!=S_OK){
ASKER CERTIFIED SOLUTION
Avatar of modulo
modulo

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial