Example #1
0
 void xpath::init_raw_(const std::string& str)
 {
     // Compile the XPath expression.
     xmlXPathCompExpr* px = xmlXPathCompile(detail::to_xml_chars(str.c_str()));
     if (px == 0)
     {
         std::string what = "fail to compile XPath expression: " + str;
         throw xpath_error(what);
     }
     // Free the underlying XPath expression object as necessary.
     if (raw_ != 0)
     {
         xmlXPathFreeCompExpr(raw_);
         raw_ = 0;
     }
     // Reset raw.
     raw_ = px;
 }
Example #2
0
int
main(int argc, char **argv) {
#else
int
xpath_locator(int argc, char **argv) {
#endif

    if (argc < 2) {
        fprintf(stderr, "Need to specify an input filename.\n"
            "Usage: xpath_locator file.xml xpath1 xpath2 ...\n");
        exit(1);
    }
    char *xml_filename = argv[1];

    num_xpaths = argc - 2;

    xpath_finders = (XPathFinder *) mmalloc(num_xpaths * sizeof(XPathFinder));

    for (int xpath_num = 0; xpath_num < num_xpaths; ++xpath_num) {
        xmlChar *xpath_expr = (xmlChar *) argv[xpath_num + 2];
        XPathFinder *xpath_finder = &xpath_finders[xpath_num];
        xpath_finder->original = new_string(xpath_expr);
        xpath_finder->current_level = 0;
        xpath_finder->line_number = 0;
        xpath_finder->column_number = 0;


        escape_uri_slashes(xpath_expr, TRUE);
        int num_segs = xpath_finder->num_segs = count_chars(xpath_expr, '/');

        XPathSegFinder *seg_finders = 
            (XPathSegFinder *) mmalloc(num_segs * sizeof(XPathSegFinder));
        xpath_finder->seg_finders = seg_finders;

        /* Extract each XPath segment */
        xmlChar *seg = xstrtok(xpath_expr, "/");
        int seg_num = 0;
        while (seg != NULL) {
            XPathSegFinder *seg_finder = &seg_finders[seg_num];
            seg_finder->count = 0;

            escape_uri_slashes(seg, FALSE);
            seg_finder->original = new_string(seg);

            // Get the element local name
            xmlChar *lns = starts_with(seg, (const xmlChar *) "*:") ? seg + 2 : seg;
            const xmlChar *bracket = xstrchr(seg, '[');
            if (!bracket) 
                xpath_error(xpath_num, xpath_finder, seg_num, "No bracket found");
            int local_name_len = bracket - lns;
            xmlChar *local_name = seg_finder->local_name = 
                new_string_n(lns, local_name_len);

            if (starts_with(bracket + 1, (const xmlChar *) "namespace-uri()=")) {
                const xmlChar *ns_start = bracket + 18;
                const xmlChar *ns_end = xstrchr(ns_start, '\'');
                if (!ns_end) 
                    xpath_error(xpath_num, xpath_finder, seg_num, 
                        "No end to the namespace URI");
                seg_finder->namespace_uri = new_string_n(ns_start, ns_end - ns_start);
                bracket = xstrchr(ns_end, '[');
                if (!bracket) 
                    xpath_error(xpath_num, xpath_finder, seg_num, "No position found");
            }
            else {
                seg_finder->namespace_uri = NULL;
            }

            const xmlChar *pos_start = bracket + 1;
            const xmlChar *pos_end = xstrchr(pos_start, ']');
            if (!pos_end) 
                xpath_error(xpath_num, xpath_finder, seg_num, "No closing bracket found");
            size_t pos_str_len = pos_end - pos_start;
            char pos_str[10];
            strncpy(pos_str, (const char *) pos_start, pos_str_len);
            pos_str[pos_str_len] = 0;
            seg_finder->position = strtol(pos_str, NULL, 10);
            if (seg_finder->position <= 0) 
                xpath_error(xpath_num, xpath_finder, seg_num, "Bad position argument");

            seg = xstrtok(NULL, "/");
            seg_num++;
        }
    }


    // Initialize default handler structure for SAX 2
    xmlSAXVersion(handlers, 2);
    handlers->startElementNs = my_startElementNs;
    handlers->endElementNs = my_endElementNs;

    parser_level = 0;  // [c] parser_level is safe
    int res = xmlSAXUserParseFile(handlers, NULL, xml_filename);

    // Output the results
    for (int xpath_num = 0; xpath_num < num_xpaths; ++xpath_num) {
        XPathFinder *xpath_finder = &xpath_finders[xpath_num];
        printf("%d:%d\n", xpath_finder->line_number, xpath_finder->column_number);
    }    


    for (int xpath_num = 0; xpath_num < num_xpaths; ++xpath_num) {
        XPathFinder *xpath_finder = &xpath_finders[xpath_num];
        int num_segs = xpath_finder->num_segs;
        XPathSegFinder *seg_finders = xpath_finder->seg_finders;
        for (int seg_num = 0; seg_num < num_segs; ++seg_num) {
            XPathSegFinder *seg_finder = &seg_finders[seg_num];
            ffree(seg_finder->original);
            ffree(seg_finder->local_name);
            ffree(seg_finder->namespace_uri);
        }

        ffree(xpath_finder->seg_finders);
        ffree(xpath_finder->original);
    }
    ffree(xpath_finders);

    return 0;
}