#include #include #include #include #include #include #include #include "xml-utils.h" #define PROG_NAME "xml-merge" #define VERSION "1.5.0" static void show_help(void) { puts("Usage: " PROG_NAME "[-fh?] "); puts(""); puts("Options:"); puts(" -f, --overwrite Overwrite file."); puts(" -h, -?, --help Show help/usage message"); puts(" --version Show version information"); puts(" dst XML file to in to"); puts(" src XML file to merge in to "); LIBXML2_PARSE_LONGOPT_HELP } static void show_version(void) { printf("%s (xml-utils) %s\n", PROG_NAME, VERSION); printf("Using libxml %s\n", xmlParserVersion); } static xmlNodePtr firstXPathNode(char *xpath, xmlDocPtr doc) { xmlXPathContextPtr ctx; xmlXPathObjectPtr obj; xmlNodePtr node; ctx = xmlXPathNewContext(doc); obj = xmlXPathEvalExpression(BAD_CAST xpath, ctx); if (xmlXPathNodeSetIsEmpty(obj->nodesetval)) node = NULL; else node = obj->nodesetval->nodeTab[0]; xmlXPathFreeObject(obj); xmlXPathFreeContext(ctx); return node; } int main(int argc, char **argv) { const char *fname1 = "-"; const char *fname2 = "-"; char xpath[256]; xmlNodePtr target1; xmlNodePtr target2; xmlDocPtr doc1; xmlDocPtr doc2; int c; const char *sopts = "fh?"; struct option lopts[] = { {"version" , no_argument, 0, 0}, {"help" , no_argument, 0, 'h'}, {"overwrite", no_argument, 0, 'f'}, LIBXML2_PARSE_LONGOPT_DEFS {0, 0, 0, 0} }; int loptind = 0; bool overwrite = false; while ((c = getopt_long(argc, argv, sopts, lopts, &loptind)) != -1) { switch (c) { case 0: if (strcmp(lopts[loptind].name, "version") == 0) { show_version(); return 0; } LIBXML2_PARSE_LONGOPT_HANDLE(lopts, loptind, optarg) break; case 'f': overwrite = true; break; case 'h': case '?': show_help(); return 0; } } if (optind < argc) fname1 = argv[optind]; if (optind + 1 < argc) fname2 = argv[optind + 1]; doc1 = read_xml_doc(fname1); doc2 = read_xml_doc(fname2); target2 = xmlDocGetRootElement(doc2); sprintf(xpath, "//%s", (char *) target2->name); target1 = firstXPathNode(xpath, doc1); if (target1) { xmlAddNextSibling(target1, xmlCopyNode(target2, 1)); xmlUnlinkNode(target1); xmlFreeNode(target1); } else { fprintf(stderr, "xml-merge: ERROR: No element %s to merge on.\n", target2->name); } if (overwrite) { save_xml_doc(doc1, fname1); } else { save_xml_doc(doc1, "-"); } xmlFreeDoc(doc1); xmlFreeDoc(doc2); xmlCleanupParser(); return 0; }