/*
 * call-seq:
 *  evaluate(search_path, handler = nil)
 *
 * Evaluate the +search_path+ returning an XML::XPath object.
 */
static VALUE evaluate(int argc, VALUE *argv, VALUE self)
{
  VALUE search_path, xpath_handler;
  VALUE thing = Qnil;
  xmlXPathContextPtr ctx;
  xmlXPathObjectPtr xpath;
  xmlChar *query;

  Data_Get_Struct(self, xmlXPathContext, ctx);

  if(rb_scan_args(argc, argv, "11", &search_path, &xpath_handler) == 1)
    xpath_handler = Qnil;

  query = (xmlChar *)StringValuePtr(search_path);

  if(Qnil != xpath_handler) {
    /* FIXME: not sure if this is the correct place to shove private data. */
    ctx->userData = (void *)xpath_handler;
    xmlXPathRegisterFuncLookup(ctx, lookup, (void *)xpath_handler);
  }

  xmlResetLastError();
  xmlSetStructuredErrorFunc(NULL, xpath_exception_handler);

  /* For some reason, xmlXPathEvalExpression will blow up with a generic error */
  /* when there is a non existent function. */
  xmlSetGenericErrorFunc(NULL, xpath_generic_exception_handler);

  xpath = xmlXPathEvalExpression(query, ctx);
  xmlSetStructuredErrorFunc(NULL, NULL);
  xmlSetGenericErrorFunc(NULL, NULL);

  if(xpath == NULL) {
    VALUE xpath = rb_const_get(mNokogiriXml, rb_intern("XPath"));
    VALUE klass = rb_const_get(xpath, rb_intern("SyntaxError"));

    xmlErrorPtr error = xmlGetLastError();
    rb_exc_raise(Nokogiri_wrap_xml_syntax_error(klass, error));
  }

  assert(ctx->doc);
  assert(DOC_RUBY_OBJECT_TEST(ctx->doc));

  switch(xpath->type) {
    case XPATH_STRING:
      thing = NOKOGIRI_STR_NEW2(xpath->stringval);
      break;
    case XPATH_NODESET:
      if(NULL == xpath->nodesetval) {
        thing = Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL),
          DOC_RUBY_OBJECT(ctx->doc));
      } else {
        thing = Nokogiri_wrap_xml_node_set(xpath->nodesetval,
            DOC_RUBY_OBJECT(ctx->doc));
      }
      break;
    case XPATH_NUMBER:
      thing = rb_float_new(xpath->floatval);
      break;
    case XPATH_BOOLEAN:
      thing = xpath->boolval == 1 ? Qtrue : Qfalse;
      break;
    default:
      thing = Nokogiri_wrap_xml_node_set(xmlXPathNodeSetCreate(NULL),
        DOC_RUBY_OBJECT(ctx->doc));
  }

  xmlXPathFreeNodeSetList(xpath);

  return thing;
}
Example #2
0
/**
 *  This is the main function for 'validate' option
 */
int
valMain(int argc, char **argv)
{
    int start;
    static valOptions ops;
    static ErrorInfo errorInfo;
    int invalidFound = 0;
    int options = XML_PARSE_DTDLOAD | XML_PARSE_DTDATTR;

    if (argc <= 2) valUsage(argc, argv, EXIT_BAD_ARGS);
    valInitOptions(&ops);
    start = valParseOptions(&ops, argc, argv);
    if (ops.nonet) options |= XML_PARSE_NONET;

    errorInfo.verbose = ops.err;
    xmlSetStructuredErrorFunc(&errorInfo, reportError);
    xmlLineNumbersDefault(1);

    if (ops.dtd)
    {
        /* xmlReader doesn't work with external dtd, have to use SAX
         * interface */
        int i;

        for (i=start; i<argc; i++)
        {
            xmlDocPtr doc;
            int ret;

            ret = 0;
            doc = NULL;

            errorInfo.filename = argv[i];
            doc = xmlReadFile(argv[i], NULL, options);
            if (doc)
            {
                /* TODO: precompile DTD once */                
                ret = valAgainstDtd(&ops, ops.dtd, doc, argv[i]);
                xmlFreeDoc(doc);
            }
            else
            {
                ret = 1; /* Malformed XML or could not open file */
                if ((ops.listGood < 0) && !ops.show_val_res)
                {
                    fprintf(stdout, "%s\n", argv[i]);
                }
            }
            if (ret) invalidFound = 1;     

            if (ops.show_val_res)
            {
                if (ret == 0)
                    fprintf(stdout, "%s - valid\n", argv[i]);
                else
                    fprintf(stdout, "%s - invalid\n", argv[i]);
            }
        }
    }
    else if (ops.schema || ops.relaxng || ops.embed || ops.wellFormed)
    {
        int i;
        xmlTextReaderPtr reader = NULL;

#ifdef LIBXML_SCHEMAS_ENABLED
        xmlSchemaPtr schema = NULL;
        xmlSchemaParserCtxtPtr schemaParserCtxt = NULL;
        xmlSchemaValidCtxtPtr schemaCtxt = NULL;

        xmlRelaxNGPtr relaxng = NULL;
        xmlRelaxNGParserCtxtPtr relaxngParserCtxt = NULL;
        /* there is no xmlTextReaderRelaxNGValidateCtxt() !?  */

        /* TODO: Do not print debug stuff */
        if (ops.schema)
        {
            schemaParserCtxt = xmlSchemaNewParserCtxt(ops.schema);
            if (!schemaParserCtxt)
            {
                invalidFound = 2;
                goto schemaCleanup;
            }
            errorInfo.filename = ops.schema;
            schema = xmlSchemaParse(schemaParserCtxt);
            if (!schema)
            {
                invalidFound = 2;
                goto schemaCleanup;
            }

            xmlSchemaFreeParserCtxt(schemaParserCtxt);
            schemaCtxt = xmlSchemaNewValidCtxt(schema);
            if (!schemaCtxt)
            {
                invalidFound = 2;
                goto schemaCleanup;
            }

        }
        else if (ops.relaxng)
        {
            relaxngParserCtxt = xmlRelaxNGNewParserCtxt(ops.relaxng);
            if (!relaxngParserCtxt)
            {
                invalidFound = 2;
                goto schemaCleanup;
            }

            errorInfo.filename = ops.relaxng;
            relaxng = xmlRelaxNGParse(relaxngParserCtxt);
            if (!relaxng)
            {
                invalidFound = 2;
                goto schemaCleanup;
            }

        }
#endif  /* LIBXML_SCHEMAS_ENABLED */

        for (i=start; i<argc; i++)
        {
            int ret = 0;
            if (ops.embed) options |= XML_PARSE_DTDVALID;

            if (!reader)
            {
                reader = xmlReaderForFile(argv[i], NULL, options);
            }
            else
            {
                ret = xmlReaderNewFile(reader, argv[i], NULL, options);
            }

            errorInfo.xmlReader = reader;
            errorInfo.filename = argv[i];

            if (reader && ret == 0)
            {
#ifdef LIBXML_SCHEMAS_ENABLED
                if (schemaCtxt)
                {
                    ret = xmlTextReaderSchemaValidateCtxt(reader,
                        schemaCtxt, 0);
                }
                else if (relaxng)
                {
                    ret = xmlTextReaderRelaxNGSetSchema(reader,
                        relaxng);
                }
#endif  /* LIBXML_SCHEMAS_ENABLED */

                if (ret == 0)
                {
                    do
                    {
                        ret = xmlTextReaderRead(reader);
                    } while (ret == 1);
                    if (ret != -1 && (schema || relaxng || ops.embed))
                        ret = !xmlTextReaderIsValid(reader);
                }
            }
            else
            {
                if (ops.err)
                    fprintf(stderr, "couldn't read file '%s'\n", errorInfo.filename);
                ret = 1; /* could not open file */
            }
            if (ret) invalidFound = 1;

            if (!ops.show_val_res)
            {
                if ((ops.listGood > 0) && (ret == 0))
                    fprintf(stdout, "%s\n", argv[i]);
                if ((ops.listGood < 0) && (ret != 0))
                    fprintf(stdout, "%s\n", argv[i]);
            }
            else
            {
                if (ret == 0)
                    fprintf(stdout, "%s - valid\n", argv[i]);
                else
                    fprintf(stdout, "%s - invalid\n", argv[i]);
            }
        }
        errorInfo.xmlReader = NULL;
        xmlFreeTextReader(reader);

#ifdef LIBXML_SCHEMAS_ENABLED
    schemaCleanup:
        xmlSchemaFreeValidCtxt(schemaCtxt);
        xmlRelaxNGFree(relaxng);
        xmlSchemaFree(schema);
        xmlRelaxNGCleanupTypes();
        xmlSchemaCleanupTypes();
#endif  /* LIBXML_SCHEMAS_ENABLED */
    }

    xmlCleanupParser();
    return invalidFound;
}
XMLDocumentParserScope::~XMLDocumentParserScope()
{
    currentDocument = m_oldDocument;
    xmlSetGenericErrorFunc(m_oldErrorContext, m_oldGenericErrorFunc);
    xmlSetStructuredErrorFunc(m_oldErrorContext, m_oldStructuredErrorFunc);
}
Example #4
0
/**
 * Parse data returned from HTTP metaserver and add it to the list of servers.
 *
 * @param body
 * The data to parse.
 * @param body_size
 * Length of the body.
 */
static void
parse_metaserver_data (const char *body, size_t body_size)
{
    HARD_ASSERT(body != NULL);

    xmlSchemaParserCtxtPtr parser_ctx = NULL;
    xmlSchemaPtr schema = NULL;
    xmlSchemaValidCtxtPtr valid_ctx = NULL;

    xmlDocPtr doc = xmlReadMemory(body, body_size, "noname.xml", NULL, 0);
    if (doc == NULL) {
        LOG(ERROR, "Failed to parse data from metaserver");
        goto out;
    }

    parser_ctx = xmlSchemaNewParserCtxt("schemas/Atrinik-ADS-7.xsd");
    if (parser_ctx == NULL) {
        LOG(ERROR, "Failed to create a schema parser context");
        goto out;
    }

    schema = xmlSchemaParse(parser_ctx);
    if (schema == NULL) {
        LOG(ERROR, "Failed to parse schema file");
        goto out;
    }

    valid_ctx = xmlSchemaNewValidCtxt(schema);
    if (valid_ctx == NULL) {
        LOG(ERROR, "Failed to create a validation context");
        goto out;
    }

    xmlSetStructuredErrorFunc(NULL, NULL);
    xmlSetGenericErrorFunc(NULL, parse_metaserver_data_error);
    xmlThrDefSetStructuredErrorFunc(NULL, NULL);
    xmlThrDefSetGenericErrorFunc(NULL, parse_metaserver_data_error);

    if (xmlSchemaValidateDoc(valid_ctx, doc) != 0) {
        LOG(ERROR, "XML verification failed.");
        goto out;
    }

    xmlNodePtr root = xmlDocGetRootElement(doc);
    if (root == NULL || !XML_STR_EQUAL(root->name, "Servers")) {
        LOG(ERROR, "No servers element found in metaserver XML");
        goto out;
    }

    xmlNodePtr last = NULL;
    for (xmlNodePtr node = root->children; node != NULL; node = node->next) {
        last = node;
    }

    for (xmlNodePtr node = last; node != NULL; node = node->prev) {
        if (!XML_STR_EQUAL(node->name, "Server")) {
            continue;
        }

        parse_metaserver_node(node);
    }

out:
    if (doc != NULL) {
            xmlFreeDoc(doc);
    }

    if (parser_ctx != NULL) {
        xmlSchemaFreeParserCtxt(parser_ctx);
    }

    if (schema != NULL) {
        xmlSchemaFree(schema);
    }

    if (valid_ctx != NULL) {
        xmlSchemaFreeValidCtxt(valid_ctx);
    }
}
Example #5
0
/**
 *  This is the main function
 */
int
main(int argc, char **argv)
{
    int ret = 0;

    xmlMemSetup(free, xmalloc, xrealloc, xstrdup);

    gGetUnicodeOptions(argc, argv);
    gInitOptions(&globalOptions);
    gParseOptions(&globalOptions, &argc, argv);
    
    xmlSetStructuredErrorFunc(&errorInfo, reportError);
    if (globalOptions.quiet)
        suppressErrors();

    if (argc <= 1)
    {
        usage(argc, argv, EXIT_BAD_ARGS);
    }
    else if (!strcmp(argv[1], "ed") || !strcmp(argv[1], "edit"))
    {
        ret = edMain(argc, argv);
    }
    else if (!strcmp(argv[1], "sel") || !strcmp(argv[1], "select"))
    {
        ret = selMain(argc, argv);
    }
    else if (!strcmp(argv[1], "tr") || !strcmp(argv[1], "transform"))
    {
        ret = trMain(argc, argv);
    }
    else if (!strcmp(argv[1], "fo") || !strcmp(argv[1], "format"))
    {
        ret = foMain(argc, argv);
    }
    else if (!strcmp(argv[1], "val") || !strcmp(argv[1], "validate"))
    {
        ret = valMain(argc, argv);
    }
    else if (!strcmp(argv[1], "el") || !strcmp(argv[1], "elements"))
    {
        ret = elMain(argc, argv);
    }
    else if (!strcmp(argv[1], "c14n") || !strcmp(argv[1], "canonic"))
    {
        ret = c14nMain(argc, argv);
    }
    else if (!strcmp(argv[1], "ls") || !strcmp(argv[1], "list"))
    {
        ret = lsMain(argc, argv);
    }
    else if (!strcmp(argv[1], "pyx") || !strcmp(argv[1], "xmln"))
    {
        ret = pyxMain(argc, argv);
    }
    else if (!strcmp(argv[1], "depyx") || !strcmp(argv[1], "p2x"))
    {
        ret = depyxMain(argc, argv);
    }
    else if (!strcmp(argv[1], "esc") || !strcmp(argv[1], "escape"))
    {
        ret = escMain(argc, argv, 1);
    }
    else if (!strcmp(argv[1], "unesc") || !strcmp(argv[1], "unescape"))
    {
        ret = escMain(argc, argv, 0);
    }
    else
    {
        usage(argc, argv, EXIT_BAD_ARGS);
    }

    exit(ret);
}