📄 xmllint.c
字号:
NULL,
referenceDebug,
charactersDebug,
ignorableWhitespaceDebug,
processingInstructionDebug,
commentDebug,
warningDebug,
errorDebug,
fatalErrorDebug,
getParameterEntityDebug,
cdataBlockDebug,
externalSubsetDebug,
XML_SAX2_MAGIC,
NULL,
startElementNsDebug,
endElementNsDebug,
NULL
};
xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
static void
testSAX(const char *filename) {
xmlSAXHandlerPtr handler;
const char *user_data = "user_data"; /* mostly for debugging */
xmlParserInputBufferPtr buf = NULL;
xmlParserInputPtr inputStream;
xmlParserCtxtPtr ctxt = NULL;
xmlSAXHandlerPtr old_sax = NULL;
callbacks = 0;
if (noout) {
handler = emptySAXHandler;
#ifdef LIBXML_SAX1_ENABLED
} else if (sax1) {
handler = debugSAXHandler;
#endif
} else {
handler = debugSAX2Handler;
}
/*
* it's not the simplest code but the most generic in term of I/O
*/
buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
if (buf == NULL) {
goto error;
}
#ifdef LIBXML_SCHEMAS_ENABLED
if (wxschemas != NULL) {
int ret;
xmlSchemaValidCtxtPtr vctxt;
vctxt = xmlSchemaNewValidCtxt(wxschemas);
xmlSchemaSetValidErrors(vctxt,
(xmlSchemaValidityErrorFunc) fprintf,
(xmlSchemaValidityWarningFunc) fprintf,
stderr);
ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
(void *)user_data);
if (repeat == 0) {
if (ret == 0) {
fprintf(stderr, "%s validates\n", filename);
} else if (ret > 0) {
fprintf(stderr, "%s fails to validate\n", filename);
progresult = XMLLINT_ERR_VALID;
} else {
fprintf(stderr, "%s validation generated an internal error\n",
filename);
progresult = XMLLINT_ERR_VALID;
}
}
xmlSchemaFreeValidCtxt(vctxt);
} else
#endif
{
/*
* Create the parser context amd hook the input
*/
ctxt = xmlNewParserCtxt();
if (ctxt == NULL) {
xmlFreeParserInputBuffer(buf);
goto error;
}
old_sax = ctxt->sax;
ctxt->sax = handler;
ctxt->userData = (void *) user_data;
inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
if (inputStream == NULL) {
xmlFreeParserInputBuffer(buf);
goto error;
}
inputPush(ctxt, inputStream);
/* do the parsing */
xmlParseDocument(ctxt);
if (ctxt->myDoc != NULL) {
fprintf(stderr, "SAX generated a doc !\n");
xmlFreeDoc(ctxt->myDoc);
ctxt->myDoc = NULL;
}
}
error:
if (ctxt != NULL) {
ctxt->sax = old_sax;
xmlFreeParserCtxt(ctxt);
}
}
/************************************************************************
* *
* Stream Test processing *
* *
************************************************************************/
#ifdef LIBXML_READER_ENABLED
static void processNode(xmlTextReaderPtr reader) {
const xmlChar *name, *value;
int type, empty;
type = xmlTextReaderNodeType(reader);
empty = xmlTextReaderIsEmptyElement(reader);
if (debug) {
name = xmlTextReaderConstName(reader);
if (name == NULL)
name = BAD_CAST "--";
value = xmlTextReaderConstValue(reader);
printf("%d %d %s %d %d",
xmlTextReaderDepth(reader),
type,
name,
empty,
xmlTextReaderHasValue(reader));
if (value == NULL)
printf("\n");
else {
printf(" %s\n", value);
}
}
#ifdef LIBXML_PATTERN_ENABLED
if (patternc) {
xmlChar *path = NULL;
int match = -1;
if (type == XML_READER_TYPE_ELEMENT) {
/* do the check only on element start */
match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
if (match) {
path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
printf("Node %s matches pattern %s\n", path, pattern);
}
}
if (patstream != NULL) {
int ret;
if (type == XML_READER_TYPE_ELEMENT) {
ret = xmlStreamPush(patstream,
xmlTextReaderConstLocalName(reader),
xmlTextReaderConstNamespaceUri(reader));
if (ret < 0) {
fprintf(stderr, "xmlStreamPush() failure\n");
xmlFreeStreamCtxt(patstream);
patstream = NULL;
} else if (ret != match) {
if (path == NULL) {
path = xmlGetNodePath(
xmlTextReaderCurrentNode(reader));
}
fprintf(stderr,
"xmlPatternMatch and xmlStreamPush disagree\n");
fprintf(stderr,
" pattern %s node %s\n",
pattern, path);
}
}
if ((type == XML_READER_TYPE_END_ELEMENT) ||
((type == XML_READER_TYPE_ELEMENT) && (empty))) {
ret = xmlStreamPop(patstream);
if (ret < 0) {
fprintf(stderr, "xmlStreamPop() failure\n");
xmlFreeStreamCtxt(patstream);
patstream = NULL;
}
}
}
if (path != NULL)
xmlFree(path);
}
#endif
}
static void streamFile(char *filename) {
xmlTextReaderPtr reader;
int ret;
#ifdef HAVE_SYS_MMAN_H
int fd = -1;
struct stat info;
const char *base = NULL;
xmlParserInputBufferPtr input = NULL;
if (memory) {
if (stat(filename, &info) < 0)
return;
if ((fd = open(filename, O_RDONLY)) < 0)
return;
base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
if (base == (void *) MAP_FAILED)
return;
reader = xmlReaderForMemory(base, info.st_size, filename,
NULL, options);
} else
#endif
reader = xmlReaderForFile(filename, NULL, options);
#ifdef LIBXML_PATTERN_ENABLED
if (pattern != NULL) {
patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
if (patternc == NULL) {
xmlGenericError(xmlGenericErrorContext,
"Pattern %s failed to compile\n", pattern);
progresult = XMLLINT_ERR_SCHEMAPAT;
pattern = NULL;
}
}
if (patternc != NULL) {
patstream = xmlPatternGetStreamCtxt(patternc);
if (patstream != NULL) {
ret = xmlStreamPush(patstream, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "xmlStreamPush() failure\n");
xmlFreeStreamCtxt(patstream);
patstream = NULL;
}
}
}
#endif
if (reader != NULL) {
#ifdef LIBXML_VALID_ENABLED
if (valid)
xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
else
#endif /* LIBXML_VALID_ENABLED */
xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
#ifdef LIBXML_SCHEMAS_ENABLED
if (relaxng != NULL) {
if ((timing) && (!repeat)) {
startTimer();
}
ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
if (ret < 0) {
xmlGenericError(xmlGenericErrorContext,
"Relax-NG schema %s failed to compile\n", relaxng);
progresult = XMLLINT_ERR_SCHEMACOMP;
relaxng = NULL;
}
if ((timing) && (!repeat)) {
endTimer("Compiling the schemas");
}
}
if (schema != NULL) {
if ((timing) && (!repeat)) {
startTimer();
}
ret = xmlTextReaderSchemaValidate(reader, schema);
if (ret < 0) {
xmlGenericError(xmlGenericErrorContext,
"XSD schema %s failed to compile\n", schema);
progresult = XMLLINT_ERR_SCHEMACOMP;
schema = NULL;
}
if ((timing) && (!repeat)) {
endTimer("Compiling the schemas");
}
}
#endif
/*
* Process all nodes in sequence
*/
if ((timing) && (!repeat)) {
startTimer();
}
ret = xmlTextReaderRead(reader);
while (ret == 1) {
if ((debug)
#ifdef LIBXML_PATTERN_ENABLED
|| (patternc)
#endif
)
processNode(reader);
ret = xmlTextReaderRead(reader);
}
if ((timing) && (!repeat)) {
#ifdef LIBXML_SCHEMAS_ENABLED
if (relaxng != NULL)
endTimer("Parsing and validating");
else
#endif
#ifdef LIBXML_VALID_ENABLED
if (valid)
endTimer("Parsing and validating");
else
#endif
endTimer("Parsing");
}
#ifdef LIBXML_VALID_ENABLED
if (valid) {
if (xmlTextReaderIsValid(reader) != 1) {
xmlGenericError(xmlGenericErrorContext,
"Document %s does not validate\n", filename);
progresult = XMLLINT_ERR_VALID;
}
}
#endif /* LIBXML_VALID_ENABLED */
#ifdef LIBXML_SCHEMAS_ENABLED
if ((relaxng != NULL) || (schema != NULL)) {
if (xmlTextReaderIsValid(reader) != 1) {
fprintf(stderr, "%s fails to validate\n", filename);
progresult = XMLLINT_ERR_VALID;
} else {
fprintf(stderr, "%s validates\n", filename);
}
}
#endif
/*
* Done, cleanup and status
*/
xmlFreeTextReader(reader);
if (ret != 0) {
fprintf(stderr, "%s : failed to parse\n", filename);
progresult = XMLLINT_ERR_UNCLASS;
}
} else {
fprintf(stderr, "Unable to open %s\n", filename);
progresult = XMLLINT_ERR_UNCLASS;
}
#ifdef LIBXML_PATTERN_ENABLED
if (patstream != NULL) {
xmlFreeStreamCtxt(patstream);
patstream = NULL;
}
#endif
#ifdef HAVE_SYS_MMAN_H
if (memory) {
xmlFreeParserInputBuffer(input);
munmap((char *) base, info.st_size);
close(fd);
}
#endif
}
static void walkDoc(xmlDocPtr doc) {
xmlTextReaderPtr reader;
int ret;
#ifdef LIBXML_PATTERN_ENABLED
xmlNodePtr root;
const xmlChar *namespaces[22];
int i;
xmlNsPtr ns;
root = xmlDocGetRootElement(doc);
for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
namespaces[i++] = ns->href;
namespaces[i++] = ns->prefix;
}
namespaces[i++] = NULL;
namespaces[i++] = NULL;
if (pattern != NULL) {
patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
0, &namespaces[0]);
if (patternc == NULL) {
xmlGenericError(xmlGenericErrorContext,
"Pattern %s failed to compile\n", pattern);
progresult = XMLLINT_ERR_SCHEMAPAT;
pattern = NULL;
}
}
if (patternc != NULL) {
patstream = xmlPatternGetStreamCtxt(patternc);
if (patstream != NULL) {
ret = xmlStreamPush(patstream, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "xmlStreamPush() failure\n");
xmlFreeStreamCtxt(patstream);
patstream = NULL;
}
}
}
#endif /* LIBXML_PATTERN_ENABLED */
reader = xmlReaderWalker(doc);
if (reader != NULL) {
if ((timing) && (!repeat)) {
startTimer();
}
ret = xmlTextReaderRead(reader);
while (ret == 1) {
if ((debug)
#ifdef LIBXML_PATTERN_ENABLED
|| (patternc)
#endif
)
processNode(reader);
ret = xmlTextReaderRead(reader);
}
if ((timing) && (!repeat)) {
endTimer("walking through the doc");
}
xmlFreeTextReader(reader);
if (ret != 0) {
fprintf(stderr, "failed to walk through the doc\n");
progresult = XMLLINT_ERR_UNCLASS;
}
} else {
fprintf(stderr, "Failed to crate a reader from the document\n");
progresult = XMLLINT_ERR_UNCLASS;
}
#ifdef LIBXML_PATTERN_ENABLED
if (patstream != NULL) {
xmlFreeStreamCtxt(patstream);
patstream = NULL;
}
#endif
}
#endif /* LIBXML_READER_ENABLED */
/************************************************************************
* *
* Tree Test processing *
* *
************************************************************************/
static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
xmlDocPtr doc = NULL;
#ifdef LIBXML_TREE_ENABLED
xmlDocPtr tmp;
#endif /* LIBXML_TREE_ENABLED */
if ((timing) && (!repeat))
startTimer();
#ifdef LIBXML_TREE_ENABLED
if (filename == NULL) {
if (generate) {
xmlNodePtr n;
doc = xmlNewDoc(BAD_CAST "1.0");
n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
xmlNodeSetContent(n, BAD_CAST "abc");
xmlDocSetRootElement(doc, n);
}
}
#endif /* LIBXML_TREE_ENABLED */
#ifdef LIBXML_HTML_ENABLED
#ifdef LIBXML_PUSH_ENABLED
else if ((html) && (push)) {
FILE *f;
#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
f = fopen(filename, "rb");
#else
f = fopen(filename, "r");
#endif
if (f != NULL) {
int res, size = 3;
char chars[4096];
htmlParserCtxtPtr ctxt;
/* if (repeat) */
size = 4096;
res = fread(chars, 1, 4, f);
if (res > 0) {
ctxt = htmlCreatePushParserCtxt(NULL, NULL,
chars, res, filename, XML_CHAR_ENCODING_NONE);
while ((res = fread(chars, 1, size, f)) > 0) {
htmlParseChunk(ctxt, chars, res, 0);
}
htmlParseChunk(ctxt, chars, 0, 1);
doc = ctxt->myDoc;
htmlFreeParserCtxt(ctxt);
}
fclose(f);
}
}
#endif /* LIBXML_PUSH_ENABLED */
else if (html) {
doc = htmlReadFile(filename, NULL, options);
}
#endif /* LIBXML_HTML_ENABLED */
else {
#ifdef LIBXML_PUSH_ENABLED
/*
* build an XML tree from a string;
*/
if (push) {
FILE *f;
/* '-' Usually means stdin -<sven@zen.org> */
if ((filename[0] == '-') && (filename[1] == 0)) {
f = stdin;
} else {
#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
f = fopen(filename, "rb");
#else
f = fopen(filename, "r");
#endif
}
if (f != NULL) {
int ret;
int res, size = 1024;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -