Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ex-dom-2.cpp
#include "p6loader.h"
#include "p6domxml.h"
#include "cconsolestream.h"
#include "cfilestream.h"
using namespace P6R;
using namespace P6EXAMPLES;
P6DECLARE_CID( p6DOMXML );
P6DECLARE_CID( p6XMLNode );
P6DECLARE_IID( IFileStreamInit );
namespace {
P6R::P6ERR getFileStream(const P6R::P6WCHAR *pszFilepath,P6R::p6IDataStream **ppIface)
{
P6ERR err;
if(P6SUCCEEDED(err = CFileStream::createInstance(NULL,VALIDATECOMPTR(IFileStreamInit,cpFileInit)))) {
if(P6SUCCEEDED(err = cpFileInit->initialize(pszFilepath))) {
err = cpFileInit.queryInterface(IID_p6IDataStream,ppIface);
}
}
return err;
}
P6R::P6ERR getDOMXML(P6R::p6IDataStream *pOutStream,P6R::p6IDOMXML **ppIface)
{
P6ERR err;
if(P6SUCCEEDED(err = p6CreateInstance(NULL,CID_p6DOMXML,VALIDATECOMPTR(p6IDOMXML,cpDOM)))) {
if(P6SUCCEEDED(err = cpDOM->initialize(P6DOMXML_NOFLAGS,pOutStream))) {
//
// Using detach() saves a reference counting operation
// and gives ownership to *ppIface.
//
cpDOM.detach(ppIface);
}
}
return err;
}
// Notice how we use the XPath components directly. XPath is also used in our XSLT processor.
//
P6R::P6ERR runDOM( P6R::p6IConsole *pConsole, p6IDataStream *pStreamDebug )
{
P6ARG args;
P6WCHAR value[100];
P6UINT32 count = 1;
P6UINT32 valueLength = 100;
P6ERR err = eOk;
// [A] Create & initialize the components we need
if (P6FAILED( err = p6GetRuntimeIface( VALIDATECOMPTR( p6ISafeString, cpStr )))) return err;
if (P6FAILED( err = getFileStream(P6CTEXT("example-dom2-xml.xml"),cpOutStream1.addressof()))) return err;
if (P6FAILED( err = getFileStream(P6CTEXT("example-dom2-json.txt"),cpOutStream2.addressof()))) return err;
if (P6FAILED( err = getDOMXML(cpOutStream1,cpDOM.addressof()))) return err;
// [B] Programatically create a DOM tree
err = cpDOM->getRootNode( cpRoot.addressof() );
err = cpRoot->setType( P6XML_DYNAMICROOT );
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpParent )))) return err;
err = cpParent->initialize( P6XMLNODE_NOFLAGS, P6XML_NONLEAF, P6TRUE, count++ );
cpParent->setName( (const P6WCHAR*)P6CTEXT("one"), 3 );
err = cpRoot->addChild( cpParent );
// -> this is now you add a namespace
err = cpParent->addAttribute( P6CTEXT("xmlns:P6R"), 9, // name
P6CTEXT("http://www.p6r.com"), 18, // value
NULL, 0 ); // URI
// -> one-one child of one
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpChild )))) return err;
err = cpChild->initialize( P6XMLNODE_NOFLAGS, P6XML_NONLEAF, P6TRUE, count++ );
cpChild->setName( P6CTEXT("one-one"), 7 );
err = cpParent->addChild( cpChild );
err = cpChild->addAttribute( P6CTEXT("id"), 2, // name
P6CTEXT("432"), 3, // value
NULL, 0 ); // URI
err = cpChild->addAttribute( P6CTEXT("lang"), 4, // name
P6CTEXT("en-US&en-ES"), 11, // value
NULL, 0 ); // URI
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpText )))) return err;
err = cpText->initialize( P6XMLNODE_NOFLAGS, P6XML_CHARS, P6TRUE, count++ );
cpText->setValue( P6CTEXT("Stony Brook University"), 22 );
err = cpChild->addChild( cpText );
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpSubChild )))) return err;
err = cpSubChild->initialize( P6XMLNODE_NOFLAGS, P6XML_LEAF, P6TRUE, count++ );
cpSubChild->setName( P6CTEXT("P6R:one-one-one"), 15 );
err = cpChild->addChild( cpSubChild );
//
// Notice here the we are reusing cpText. This is
// safe because VALIDATECOMPTR() uses the addressofWithRelease()
// method of the smart pointer to store the interface. As a
// result, any existing interface is release()'d.
//
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpText )))) return err;
err = cpText->initialize( P6XMLNODE_NOFLAGS, P6XML_CHARS, P6TRUE, count++ );
cpText->setValue( P6CTEXT("13,000 students"), 15 );
err = cpSubChild->addChild( cpText );
//s
// -> one-two child of one, empty tag
//
// Again, notice that we are reusing cpChild
// and that VALIDATECOMPTR() will handle
// releasing the existing interface.
//
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpChild )))) return err;
err = cpChild->initialize( P6XMLNODE_NOFLAGS, P6XML_LEAF, P6TRUE, count++ );
cpChild->setName( P6CTEXT("one-two"), 7 );
err = cpParent->addChild( cpChild ); // this increments the ref count on pChild by one to keep it around, so we release our hold on the component with the following release
//
// -> one-three child of one
//
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpChild )))) return err;
err = cpChild->initialize( P6XMLNODE_NOFLAGS, P6XML_NONLEAF, P6TRUE, count++ );
cpChild->setName( P6CTEXT("one-three"), 9 );
err = cpParent->addChild( cpChild );
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpSubChild )))) return err;
err = cpSubChild->initialize( P6XMLNODE_NOFLAGS, P6XML_LEAF, P6TRUE, count++ );
cpSubChild->setName( P6CTEXT("one-three-one"), 13 );
err = cpChild->addChild( cpSubChild );
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpText )))) return err;
err = cpText->initialize( P6XMLNODE_NOFLAGS, P6XML_CHARS, P6TRUE, count++ );
cpText->setValue( P6CTEXT("University of California, Los Angeles"), 37 );
err = cpSubChild->addChild( cpText );
// -> add a group of nodes with same name, should produce an array in JSON output
for( P6UINT32 k=0; k < 3; k++ )
{
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpChild )))) return err;
err = cpChild->initialize( P6XMLNODE_NOFLAGS, P6XML_LEAF, P6TRUE, count++ );
cpChild->setName( P6CTEXT("one-four"), 8 );
err = cpParent->addChild( cpChild );
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpText )))) return err;
err = cpText->initialize( P6XMLNODE_NOFLAGS, P6XML_CHARS, P6TRUE, count++ );
valueLength = 100;
P6AI_UINT32( &args, k+1 );
cpStr->formatStringW( value, valueLength, &valueLength, P6CTEXT("red car #%1$"), &args, 1 );
cpText->setValue( (const P6WCHAR*)value, 10 );
err = cpChild->addChild( cpText );
}
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpChild )))) return err;
err = cpChild->initialize( P6XMLNODE_NOFLAGS, P6XML_LEAF, P6TRUE, count++ );
cpChild->setName( P6CTEXT("one-five"), 8 );
err = cpParent->addChild( cpChild );
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpText )))) return err;
err = cpText->initialize( P6XMLNODE_NOFLAGS, P6XML_CHARS, P6TRUE, count++ );
cpText->setValue( P6CTEXT("end of items"), 12 );
err = cpChild->addChild( cpText );
// -> Array of nonleafs
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpChild )))) return err;
err = cpChild->initialize( P6XMLNODE_NOFLAGS, P6XML_LEAF, P6TRUE, count++ );
cpChild->setName( P6CTEXT("one-six"), 7 );
err = cpParent->addChild( cpChild );
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpText )))) return err;
err = cpText->initialize( P6XMLNODE_NOFLAGS, P6XML_CHARS, P6TRUE, count++ );
cpText->setValue( P6CTEXT("44"), 2 );
err = cpChild->addChild( cpText );
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpChild )))) return err;
err = cpChild->initialize( P6XMLNODE_NOFLAGS, P6XML_LEAF, P6TRUE, count++ );
cpChild->setName( P6CTEXT("one-six"), 7 );
err = cpParent->addChild( cpChild );
if (P6FAILED( err = p6CreateInstance( NULL, CID_p6XMLNode, VALIDATECOMPTR( p6IXMLNode, cpText )))) return err;
err = cpText->initialize( P6XMLNODE_NOFLAGS, P6XML_CHARS, P6TRUE, count++ );
cpText->setValue( P6CTEXT("197"), 3 );
err = cpChild->addChild( cpText );
// -> same tree output in 2 different ways
err = cpDOM->output( cpOutStream1, P6DOMOUTPUT_XML );
err = cpDOM->output( cpOutStream2, P6DOMOUTPUT_JSON );
if (P6FAILED( err )) {
P6AI_ERR(&args,err);
pConsole->writeStdout("example failed [ %1$ ]\n",&args,1,NULL);
}
return err;
}
}
int main(int argc,char *argv[])
{
p6ComPtr<p6IDataStream> cpDebugStream;
P6ERR err = eOk;
if ( P6SUCCEEDED(err = CConsoleStream::createInstance( NULL, VALIDATECOMPTR( p6IDataStream, cpDebugStream ))))
{
if ( P6SUCCEEDED(err = p6InitializeLoader( cpDebugStream, 9, P6SCLF_NOFLAGS )))
{
P6ARG args[1];
err = runDOM( cpConsole, cpDebugStream );
P6AI_ERR(&args[0],err);
cpConsole->writeStdout("runDOM result: [ %1$ ]\n",&args[0],1,NULL);
//
// Make sure to release the console interface
// before calling p6CleanupLoader() !! In this
// instance we don't let the smart pointer
// handle the cleanup.
//
cpConsole = NULL;
}
}
else printf("ERROR: Failed to initialize the loader [ %x ]\n", err );
}
else printf( "ERROR: Failed to create CConsoleStream [ %x ]\n", err );
return err;
}