/* * 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; }
/** * 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); }
/** * 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); } }
/** * 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); }