version 1.4, 1998/08/13 21:35:02
|
version 1.5, 1998/10/26 01:38:59
|
Line 1
|
Line 1
|
/* |
/* |
* SAX.c : Default SAX handler to build a tree. |
* SAX.c : Default SAX handler to build a tree. |
|
* |
|
* Daniel Veillard <Daniel.Veillard@w3.org> |
*/ |
*/ |
|
|
#include <stdio.h> |
#include <stdio.h> |
#include <malloc.h> |
#include <stdlib.h> |
#include "tree.h" |
#include "tree.h" |
#include "parser.h" |
#include "parser.h" |
|
#include "entities.h" |
|
#include "error.h" |
|
|
/* #define DEBUG_SAX */ |
/* #define DEBUG_SAX */ |
|
|
/* |
/** |
|
* getPublicId: |
|
* @ctxt: An XML parser context |
|
* |
* Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN" |
* Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN" |
|
* |
|
* return values: a CHAR * |
*/ |
*/ |
const CHAR *getPublicId(xmlParserCtxtPtr ctxt) { |
const CHAR * |
|
getPublicId(xmlParserCtxtPtr ctxt) |
|
{ |
return(NULL); |
return(NULL); |
} |
} |
|
|
/* |
/** |
|
* getSystemId: |
|
* @ctxt: An XML parser context |
|
* |
* Return the system ID, basically URI or filename e.g. |
* Return the system ID, basically URI or filename e.g. |
* http://www.sgmlsource.com/dtds/memo.dtd |
* http://www.sgmlsource.com/dtds/memo.dtd |
*/ |
* |
const CHAR *getSystemId(xmlParserCtxtPtr ctxt) { |
* return values: a CHAR * |
|
*/ |
|
const CHAR * |
|
getSystemId(xmlParserCtxtPtr ctxt) |
|
{ |
return(ctxt->input->filename); |
return(ctxt->input->filename); |
} |
} |
|
|
/* |
/** |
|
* getLineNumber: |
|
* @ctxt: An XML parser context |
|
* |
* Return the line number of the current parsing point. |
* Return the line number of the current parsing point. |
|
* |
|
* return values: an int |
*/ |
*/ |
int getLineNumber(xmlParserCtxtPtr ctxt) { |
int |
|
getLineNumber(xmlParserCtxtPtr ctxt) |
|
{ |
return(ctxt->input->line); |
return(ctxt->input->line); |
} |
} |
/* |
|
|
/** |
|
* getColumnNumber: |
|
* @ctxt: An XML parser context |
|
* |
* Return the column number of the current parsing point. |
* Return the column number of the current parsing point. |
|
* |
|
* return values: an int |
*/ |
*/ |
int getColumnNumber(xmlParserCtxtPtr ctxt) { |
int |
|
getColumnNumber(xmlParserCtxtPtr ctxt) |
|
{ |
return(ctxt->input->col); |
return(ctxt->input->col); |
} |
} |
|
|
Line 45 xmlSAXLocator xmlDefaultSAXLocator = {
|
Line 78 xmlSAXLocator xmlDefaultSAXLocator = {
|
getPublicId, getSystemId, getLineNumber, getColumnNumber |
getPublicId, getSystemId, getLineNumber, getColumnNumber |
}; |
}; |
|
|
/* |
/** |
|
* resolveEntity: |
|
* @ctxt: An XML parser context |
|
* @publicId: The public ID of the entity |
|
* @systemId: The system ID of the entity |
|
* |
* Special entity resolver, better left to the parser, it has |
* Special entity resolver, better left to the parser, it has |
* more context than the application layer. |
* more context than the application layer. |
*/ |
* The default behaviour is to NOT resolve the entities, in that case |
xmlParserInputPtr resolveEntity(xmlParserCtxtPtr ctxt, |
* the ENTITY_REF nodes are built in the structure (and the parameter |
const CHAR *publicId, const CHAR *systemId) { |
* values). However the "standard" entities are resoled except '&' |
|
* |
|
* return values: an int |
|
*/ |
|
xmlParserInputPtr |
|
resolveEntity(xmlParserCtxtPtr ctxt, const CHAR *publicId, const CHAR *systemId) |
|
{ |
|
xmlEntityPtr entity; |
|
xmlParserInputPtr input; |
|
|
#ifdef DEBUG_SAX |
#ifdef DEBUG_SAX |
fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId); |
fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId); |
#endif |
#endif |
|
|
|
entity = xmlGetPredefinedEntity(systemId); |
|
if (entity != NULL) { |
|
/* |
|
* Avoid some madness with the '&' |
|
*/ |
|
if (entity->content[0] == '&') |
|
return(NULL); |
|
input = xmlNewEntityInputStream(ctxt, entity); |
|
return(input); |
|
} |
|
/* |
|
* If we can get the content, push the entity content |
|
* as the next input stream. |
|
entity = xmlGetDocEntity(ctxt->doc, systemId); |
|
if (entity == NULL) { |
|
xmlParserWarning(ctxt, |
|
"xmlParseEntityRef: &%s; not found\n", name); |
|
} |
|
else { |
|
switch (entity->type) { |
|
case XML_INTERNAL_PARAMETER_ENTITY: |
|
case XML_EXTERNAL_PARAMETER_ENTITY: |
|
xmlParserError(ctxt, |
|
"internal: xmlGetDtdEntity returned a general entity\n"); |
|
break; |
|
case XML_INTERNAL_GENERAL_ENTITY: |
|
if (inLine) |
|
ret = entity->content; |
|
else |
|
xmlHandleEntity(ctxt, entity); |
|
break; |
|
case XML_EXTERNAL_GENERAL_PARSED_ENTITY: |
|
case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: |
|
xmlParserWarning(ctxt, |
|
"xmlParseEntityRef: external entity &%s; not supported\n", |
|
name); |
|
break; |
|
default: |
|
xmlParserError(ctxt, |
|
"internal: xmlParseEntityRef: unknown entity type %d\n", |
|
entity->type); |
|
} |
|
} |
|
*/ |
return(NULL); |
return(NULL); |
} |
} |
|
|
/* |
/** |
|
* notationDecl: |
|
* @ctxt: An XML parser context |
|
* @name: The name of the notation |
|
* @publicId: The public ID of the entity |
|
* @systemId: The system ID of the entity |
|
* |
* What to do when a notation declaration has been parsed. |
* What to do when a notation declaration has been parsed. |
* TODO Not handled currently. |
* TODO Not handled currently. |
|
* |
|
* return values: |
*/ |
*/ |
void notationDecl(xmlParserCtxtPtr ctxt, const CHAR *name, |
void |
const CHAR *publicId, const CHAR *systemId) { |
notationDecl(xmlParserCtxtPtr ctxt, const CHAR *name, |
|
const CHAR *publicId, const CHAR *systemId) |
|
{ |
#ifdef DEBUG_SAX |
#ifdef DEBUG_SAX |
fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId); |
fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId); |
#endif |
#endif |
} |
} |
|
|
/* |
/** |
|
* unparsedEntityDecl: |
|
* @ctxt: An XML parser context |
|
* @name: The name of the entity |
|
* @publicId: The public ID of the entity |
|
* @systemId: The system ID of the entity |
|
* @notationName: the name of the notation |
|
* |
* What to do when an unparsed entity declaration is parsed |
* What to do when an unparsed entity declaration is parsed |
* TODO Create an Entity node. |
* TODO Create an Entity node. |
|
* |
|
* return values: |
*/ |
*/ |
void unparsedEntityDecl(xmlParserCtxtPtr ctxt, const CHAR *name, |
void |
const CHAR *publicId, const CHAR *systemId, |
unparsedEntityDecl(xmlParserCtxtPtr ctxt, const CHAR *name, |
const CHAR *notationName) { |
const CHAR *publicId, const CHAR *systemId, |
|
const CHAR *notationName) |
|
{ |
#ifdef DEBUG_SAX |
#ifdef DEBUG_SAX |
fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n", |
fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n", |
name, publicId, systemId, notationName); |
name, publicId, systemId, notationName); |
#endif |
#endif |
} |
} |
|
|
/* |
/** |
|
* setDocumentLocator: |
|
* @ctxt: An XML parser context |
|
* @loc: A SAX Locator |
|
* |
* Receive the document locator at startup, actually xmlDefaultSAXLocator |
* Receive the document locator at startup, actually xmlDefaultSAXLocator |
* Everything is available on the context, so this is useless in our case. |
* Everything is available on the context, so this is useless in our case. |
|
* |
|
* return values: |
*/ |
*/ |
void setDocumentLocator(xmlParserCtxtPtr ctxt, xmlSAXLocatorPtr loc) { |
void |
|
setDocumentLocator(xmlParserCtxtPtr ctxt, xmlSAXLocatorPtr loc) |
|
{ |
#ifdef DEBUG_SAX |
#ifdef DEBUG_SAX |
fprintf(stderr, "SAX.setDocumentLocator()\n"); |
fprintf(stderr, "SAX.setDocumentLocator()\n"); |
#endif |
#endif |
} |
} |
|
|
/* |
/** |
|
* startDocument: |
|
* @ctxt: An XML parser context |
|
* |
* called when the document start being processed. |
* called when the document start being processed. |
|
* |
|
* return values: |
*/ |
*/ |
void startDocument(xmlParserCtxtPtr ctxt) { |
void |
|
startDocument(xmlParserCtxtPtr ctxt) |
|
{ |
#ifdef DEBUG_SAX |
#ifdef DEBUG_SAX |
fprintf(stderr, "SAX.startDocument()\n"); |
fprintf(stderr, "SAX.startDocument()\n"); |
#endif |
#endif |
} |
} |
|
|
/* |
/** |
|
* endDocument: |
|
* @ctxt: An XML parser context |
|
* |
* called when the document end has been detected. |
* called when the document end has been detected. |
|
* |
|
* return values: |
*/ |
*/ |
void endDocument(xmlParserCtxtPtr ctxt) { |
void |
|
endDocument(xmlParserCtxtPtr ctxt) |
|
{ |
#ifdef DEBUG_SAX |
#ifdef DEBUG_SAX |
fprintf(stderr, "SAX.endDocument()\n"); |
fprintf(stderr, "SAX.endDocument()\n"); |
#endif |
#endif |
} |
} |
|
|
/* |
/** |
|
* startElement: |
|
* @ctxt: An XML parser context |
|
* @name: The element name |
|
* |
* called when an opening tag has been processed. |
* called when an opening tag has been processed. |
* TODO We currently have a small pblm with the arguments ... |
* TODO We currently have a small pblm with the arguments ... |
|
* |
|
* return values: |
*/ |
*/ |
void startElement(xmlParserCtxtPtr ctxt, const CHAR *name) { |
void |
|
startElement(xmlParserCtxtPtr ctxt, const CHAR *name) |
|
{ |
xmlNodePtr parent; |
xmlNodePtr parent; |
|
|
#ifdef DEBUG_SAX |
#ifdef DEBUG_SAX |
Line 127 void startElement(xmlParserCtxtPtr ctxt,
|
Line 269 void startElement(xmlParserCtxtPtr ctxt,
|
|
|
} |
} |
|
|
/* |
/** |
|
* endElement: |
|
* @ctxt: An XML parser context |
|
* @name: The element name |
|
* |
* called when the end of an element has been detected. |
* called when the end of an element has been detected. |
|
* |
|
* return values: |
*/ |
*/ |
void endElement(xmlParserCtxtPtr ctxt, const CHAR *name) { |
void |
|
endElement(xmlParserCtxtPtr ctxt, const CHAR *name) |
|
{ |
#ifdef DEBUG_SAX |
#ifdef DEBUG_SAX |
fprintf(stderr, "SAX.endElement(%s)\n", name); |
fprintf(stderr, "SAX.endElement(%s)\n", name); |
#endif |
#endif |
} |
} |
|
|
/* |
/** |
|
* attribute: |
|
* @ctxt: An XML parser context |
|
* @name: The attribute name |
|
* @value: The attribute value |
|
* |
|
* called when an attribute has been read by the parser. |
|
* The default handling is to convert the attribute into an |
|
* DOM subtree and past it in a new xmlAttr element added to |
|
* the element. |
|
* |
|
* return values: |
|
*/ |
|
void |
|
attribute(xmlParserCtxtPtr ctxt, const CHAR *name, const CHAR *value) |
|
{ |
|
#ifdef DEBUG_SAX |
|
fprintf(stderr, "SAX.attribute(%s, %s)\n", name, value); |
|
#endif |
|
xmlNewProp(ctxt->node, name, value); |
|
} |
|
|
|
/** |
|
* characters: |
|
* @ctxt: An XML parser context |
|
* @ch: a CHAR string |
|
* @start: the first char in the string |
|
* @len: the number of CHAR |
|
* |
* receiving some chars from the parser. |
* receiving some chars from the parser. |
* Question: how much at a time ??? |
* Question: how much at a time ??? |
|
* |
|
* return values: |
*/ |
*/ |
void characters(xmlParserCtxtPtr ctxt, const CHAR *ch, |
void |
int start, int len) { |
characters(xmlParserCtxtPtr ctxt, const CHAR *ch, int start, int len) |
|
{ |
xmlNodePtr lastChild; |
xmlNodePtr lastChild; |
|
|
#ifdef DEBUG_SAX |
#ifdef DEBUG_SAX |
Line 166 void characters(xmlParserCtxtPtr ctxt, c
|
Line 347 void characters(xmlParserCtxtPtr ctxt, c
|
} |
} |
} |
} |
|
|
/* |
/** |
|
* ignorableWhitespace: |
|
* @ctxt: An XML parser context |
|
* @ch: a CHAR string |
|
* @start: the first char in the string |
|
* @len: the number of CHAR |
|
* |
* receiving some ignorable whitespaces from the parser. |
* receiving some ignorable whitespaces from the parser. |
* Question: how much at a time ??? |
* Question: how much at a time ??? |
|
* |
|
* return values: |
*/ |
*/ |
void ignorableWhitespace(xmlParserCtxtPtr ctxt, const CHAR *ch, |
void |
int start, int len) { |
ignorableWhitespace(xmlParserCtxtPtr ctxt, const CHAR *ch, int start, int len) |
|
{ |
#ifdef DEBUG_SAX |
#ifdef DEBUG_SAX |
fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d, %d)\n", ch, start, len); |
fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d, %d)\n", ch, start, len); |
#endif |
#endif |
} |
} |
|
|
/* |
/** |
* A processing instruction has beem parsed. |
* processingInstruction: |
*/ |
* @ctxt: An XML parser context |
void processingInstruction(xmlParserCtxtPtr ctxt, const CHAR *target, |
* @target: the target name |
const CHAR *data) { |
* @data: the PI data's |
|
* @len: the number of CHAR |
|
* |
|
* A processing instruction has been parsed. |
|
* |
|
* return values: |
|
*/ |
|
void |
|
processingInstruction(xmlParserCtxtPtr ctxt, const CHAR *target, |
|
const CHAR *data) |
|
{ |
#ifdef DEBUG_SAX |
#ifdef DEBUG_SAX |
fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data); |
fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data); |
#endif |
#endif |
Line 196 xmlSAXHandler xmlDefaultSAXHandler = {
|
Line 396 xmlSAXHandler xmlDefaultSAXHandler = {
|
endDocument, |
endDocument, |
startElement, |
startElement, |
endElement, |
endElement, |
|
attribute, |
characters, |
characters, |
ignorableWhitespace, |
ignorableWhitespace, |
processingInstruction, |
processingInstruction, |
Line 204 xmlSAXHandler xmlDefaultSAXHandler = {
|
Line 405 xmlSAXHandler xmlDefaultSAXHandler = {
|
xmlParserError, |
xmlParserError, |
}; |
}; |
|
|
void xmlDefaultSAXHandlerInit(void) { |
/** |
|
* xmlDefaultSAXHandlerInit: |
|
* |
|
* Initialize the default SAX handler |
|
*/ |
|
void |
|
xmlDefaultSAXHandlerInit(void) |
|
{ |
xmlDefaultSAXHandler.resolveEntity = resolveEntity; |
xmlDefaultSAXHandler.resolveEntity = resolveEntity; |
xmlDefaultSAXHandler.notationDecl = notationDecl; |
xmlDefaultSAXHandler.notationDecl = notationDecl; |
xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl; |
xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl; |
Line 213 void xmlDefaultSAXHandlerInit(void) {
|
Line 421 void xmlDefaultSAXHandlerInit(void) {
|
xmlDefaultSAXHandler.endDocument = endDocument; |
xmlDefaultSAXHandler.endDocument = endDocument; |
xmlDefaultSAXHandler.startElement = startElement; |
xmlDefaultSAXHandler.startElement = startElement; |
xmlDefaultSAXHandler.endElement = endElement; |
xmlDefaultSAXHandler.endElement = endElement; |
|
xmlDefaultSAXHandler.attribute = attribute; |
xmlDefaultSAXHandler.characters = characters; |
xmlDefaultSAXHandler.characters = characters; |
xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace; |
xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace; |
xmlDefaultSAXHandler.processingInstruction = processingInstruction; |
xmlDefaultSAXHandler.processingInstruction = processingInstruction; |