| /* |
| * SAX.c : Default SAX handler to build a tree. |
| * |
| * Daniel Veillard <Daniel.Veillard@w3.org> |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include "tree.h" |
| #include "parser.h" |
| #include "entities.h" |
| #include "error.h" |
| |
| /* #define DEBUG_SAX */ |
| |
| /** |
| * getPublicId: |
| * @ctxt: An XML parser context |
| * |
| * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN" |
| * |
| * return values: a CHAR * |
| */ |
| const CHAR * |
| getPublicId(xmlParserCtxtPtr ctxt) |
| { |
| return(NULL); |
| } |
| |
| /** |
| * getSystemId: |
| * @ctxt: An XML parser context |
| * |
| * Return the system ID, basically URI or filename e.g. |
| * http://www.sgmlsource.com/dtds/memo.dtd |
| * |
| * return values: a CHAR * |
| */ |
| const CHAR * |
| getSystemId(xmlParserCtxtPtr ctxt) |
| { |
| return(ctxt->input->filename); |
| } |
| |
| /** |
| * getLineNumber: |
| * @ctxt: An XML parser context |
| * |
| * Return the line number of the current parsing point. |
| * |
| * return values: an int |
| */ |
| int |
| getLineNumber(xmlParserCtxtPtr ctxt) |
| { |
| return(ctxt->input->line); |
| } |
| |
| /** |
| * getColumnNumber: |
| * @ctxt: An XML parser context |
| * |
| * Return the column number of the current parsing point. |
| * |
| * return values: an int |
| */ |
| int |
| getColumnNumber(xmlParserCtxtPtr ctxt) |
| { |
| return(ctxt->input->col); |
| } |
| |
| /* |
| * The default SAX Locator. |
| */ |
| |
| xmlSAXLocator xmlDefaultSAXLocator = { |
| 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 |
| * more context than the application layer. |
| * The default behaviour is to NOT resolve the entities, in that case |
| * the ENTITY_REF nodes are built in the structure (and the parameter |
| * values). |
| * |
| * return values: the xmlParserInputPtr if inlined or NULL for DOM behaviour. |
| */ |
| xmlParserInputPtr |
| resolveEntity(xmlParserCtxtPtr ctxt, const CHAR *publicId, const CHAR *systemId) |
| { |
| |
| #ifdef DEBUG_SAX |
| fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId); |
| #endif |
| |
| 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. |
| * TODO Not handled currently. |
| * |
| * return values: |
| */ |
| void |
| notationDecl(xmlParserCtxtPtr ctxt, const CHAR *name, |
| const CHAR *publicId, const CHAR *systemId) |
| { |
| #ifdef DEBUG_SAX |
| fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId); |
| #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 |
| * TODO Create an Entity node. |
| * |
| * return values: |
| */ |
| void |
| unparsedEntityDecl(xmlParserCtxtPtr ctxt, const CHAR *name, |
| const CHAR *publicId, const CHAR *systemId, |
| const CHAR *notationName) |
| { |
| #ifdef DEBUG_SAX |
| fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n", |
| name, publicId, systemId, notationName); |
| #endif |
| } |
| |
| /** |
| * setDocumentLocator: |
| * @ctxt: An XML parser context |
| * @loc: A SAX Locator |
| * |
| * Receive the document locator at startup, actually xmlDefaultSAXLocator |
| * Everything is available on the context, so this is useless in our case. |
| * |
| * return values: |
| */ |
| void |
| setDocumentLocator(xmlParserCtxtPtr ctxt, xmlSAXLocatorPtr loc) |
| { |
| #ifdef DEBUG_SAX |
| fprintf(stderr, "SAX.setDocumentLocator()\n"); |
| #endif |
| } |
| |
| /** |
| * startDocument: |
| * @ctxt: An XML parser context |
| * |
| * called when the document start being processed. |
| * |
| * return values: |
| */ |
| void |
| startDocument(xmlParserCtxtPtr ctxt) |
| { |
| #ifdef DEBUG_SAX |
| fprintf(stderr, "SAX.startDocument()\n"); |
| #endif |
| } |
| |
| /** |
| * endDocument: |
| * @ctxt: An XML parser context |
| * |
| * called when the document end has been detected. |
| * |
| * return values: |
| */ |
| void |
| endDocument(xmlParserCtxtPtr ctxt) |
| { |
| #ifdef DEBUG_SAX |
| fprintf(stderr, "SAX.endDocument()\n"); |
| #endif |
| } |
| |
| /** |
| * startElement: |
| * @ctxt: An XML parser context |
| * @name: The element name |
| * |
| * called when an opening tag has been processed. |
| * TODO We currently have a small pblm with the arguments ... |
| * |
| * return values: |
| */ |
| void |
| startElement(xmlParserCtxtPtr ctxt, const CHAR *name) |
| { |
| #ifdef DEBUG_SAX |
| fprintf(stderr, "SAX.startElement(%s)\n", name); |
| #endif |
| } |
| |
| /** |
| * endElement: |
| * @ctxt: An XML parser context |
| * @name: The element name |
| * |
| * called when the end of an element has been detected. |
| * |
| * return values: |
| */ |
| void |
| endElement(xmlParserCtxtPtr ctxt, const CHAR *name) |
| { |
| #ifdef DEBUG_SAX |
| fprintf(stderr, "SAX.endElement(%s)\n", name); |
| #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 |
| } |
| |
| /** |
| * 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. |
| * Question: how much at a time ??? |
| * |
| * return values: |
| */ |
| void |
| characters(xmlParserCtxtPtr ctxt, const CHAR *ch, int start, int len) |
| { |
| xmlNodePtr lastChild; |
| |
| #ifdef DEBUG_SAX |
| fprintf(stderr, "SAX.characters(%.30s, %d, %d)\n", ch, start, len); |
| #endif |
| /* |
| * Handle the data if any. If there is no child |
| * add it as content, otherwise if the last child is text, |
| * concatenate it, else create a new node of type text. |
| */ |
| |
| lastChild = xmlGetLastChild(ctxt->node); |
| if (lastChild == NULL) |
| xmlNodeAddContentLen(ctxt->node, &ch[start], len); |
| else { |
| if (xmlNodeIsText(lastChild)) |
| xmlTextConcat(lastChild, &ch[start], len); |
| else { |
| lastChild = xmlNewTextLen(&ch[start], len); |
| xmlAddChild(ctxt->node, lastChild); |
| } |
| } |
| } |
| |
| /** |
| * 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. |
| * Question: how much at a time ??? |
| * |
| * return values: |
| */ |
| void |
| ignorableWhitespace(xmlParserCtxtPtr ctxt, const CHAR *ch, int start, int len) |
| { |
| #ifdef DEBUG_SAX |
| fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d, %d)\n", ch, start, len); |
| #endif |
| } |
| |
| /** |
| * processingInstruction: |
| * @ctxt: An XML parser context |
| * @target: the target name |
| * @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 |
| fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data); |
| #endif |
| } |
| |
| xmlSAXHandler xmlDefaultSAXHandler = { |
| resolveEntity, |
| notationDecl, |
| unparsedEntityDecl, |
| setDocumentLocator, |
| startDocument, |
| endDocument, |
| startElement, |
| endElement, |
| attribute, |
| characters, |
| ignorableWhitespace, |
| processingInstruction, |
| xmlParserWarning, |
| xmlParserError, |
| xmlParserError, |
| }; |
| |
| /** |
| * xmlDefaultSAXHandlerInit: |
| * |
| * Initialize the default SAX handler |
| */ |
| void |
| xmlDefaultSAXHandlerInit(void) |
| { |
| xmlDefaultSAXHandler.resolveEntity = resolveEntity; |
| xmlDefaultSAXHandler.notationDecl = notationDecl; |
| xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl; |
| xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator; |
| xmlDefaultSAXHandler.startDocument = startDocument; |
| xmlDefaultSAXHandler.endDocument = endDocument; |
| xmlDefaultSAXHandler.startElement = startElement; |
| xmlDefaultSAXHandler.endElement = endElement; |
| xmlDefaultSAXHandler.attribute = attribute; |
| xmlDefaultSAXHandler.characters = characters; |
| xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace; |
| xmlDefaultSAXHandler.processingInstruction = processingInstruction; |
| xmlDefaultSAXHandler.warning = xmlParserWarning; |
| xmlDefaultSAXHandler.error = xmlParserError; |
| xmlDefaultSAXHandler.fatalError = xmlParserError; |
| } |