libopc
opc_relation.c

Demonstrates how to traverse all relations in an OPC container using the API.

/*
Traverse all relations of an OPC container or get the type of an relation.
Ussage:
* Traverse all relations:
opc_relation FILENAME
* Get type of root relation
opc_relation FILENAME RELATIONID
* Get type of part relation
opc_relation FILENAME PARTNAME RELATIONID
Sample:
opc_relation OOXMLI1.docx
opc_relation OOXMLI1.docx "rId1"
opc_relation OOXMLI1.docx "word/document.xml" "rId1"
*/
#include <opc/opc.h>
#ifdef WIN32
#include <crtdbg.h>
#endif
static void traverse(opcContainer *c, opcPart source) {
for(opcRelation rel=opcRelationFirst(c, source);OPC_RELATION_INVALID!=rel;rel=opcRelationNext(c, source, rel)) {
opcPart target=opcRelationGetInternalTarget(c, source, rel);
if (OPC_PART_INVALID!=target) {
const xmlChar *prefix=NULL;
opc_uint32_t counter=-1;
const xmlChar *type=NULL;
opcRelationGetInformation(c, source, rel, &prefix, &counter, &type);
char buf[20]="";
if (-1!=counter) {
sprintf(buf, "%i", counter);
}
printf("%s %s%s %s %s\n", source, prefix, buf, target, type);
traverse(c, target);
}
}
}
int main( int argc, const char* argv[] )
{
#ifdef WIN32
_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
opcContainer *c=opcContainerOpen(_X(argv[1]), OPC_OPEN_READ_ONLY, NULL, NULL);
if (NULL!=c) {
if (3==argc) {
opcRelation rel=opcRelationFind(c, OPC_PART_INVALID, _X(argv[2]), NULL);
const xmlChar *type=NULL;
opcRelationGetInformation(c, OPC_PART_INVALID, rel, NULL, NULL, &type);
printf("type=%s\n", type);
}
} else if (4==argc) {
opcPart part=opcPartFind(c, _X(argv[2]), NULL, 0);
if (OPC_PART_INVALID!=part) {
opcRelation rel=opcRelationFind(c, part, _X(argv[3]), NULL);
const xmlChar *type=NULL;
opcRelationGetInformation(c, part, rel, NULL, NULL, &type);
printf("type=%s\n", type);
}
}
} else {
traverse(c, OPC_PART_INVALID);
}
}
#ifdef WIN32
OPC_ASSERT(!_CrtDumpMemoryLeaks());
#endif
return 0;
}