⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlreader.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
    }
    reader->state = oldstate;
    return(0);
}

#ifdef LIBXML_REGEXP_ENABLED
/**
 * xmlTextReaderValidatePush:
 * @reader:  the xmlTextReaderPtr used
 *
 * Push the current node for validation
 */
static void
xmlTextReaderValidatePush(xmlTextReaderPtr reader ATTRIBUTE_UNUSED) {
    xmlNodePtr node = reader->node;

#ifdef LIBXML_VALID_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
        (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
	if ((node->ns == NULL) || (node->ns->prefix == NULL)) {
	    reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,
				    reader->ctxt->myDoc, node, node->name);
	} else {
	    /* TODO use the BuildQName interface */
	    xmlChar *qname;

	    qname = xmlStrdup(node->ns->prefix);
	    qname = xmlStrcat(qname, BAD_CAST ":");
	    qname = xmlStrcat(qname, node->name);
	    reader->ctxt->valid &= xmlValidatePushElement(&reader->ctxt->vctxt,
				    reader->ctxt->myDoc, node, qname);
	    if (qname != NULL)
		xmlFree(qname);
	}
    }
#endif /* LIBXML_VALID_ENABLED */
#ifdef LIBXML_SCHEMAS_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
               (reader->rngValidCtxt != NULL)) {
	int ret;

	if (reader->rngFullNode != NULL) return;
	ret = xmlRelaxNGValidatePushElement(reader->rngValidCtxt,
	                                    reader->ctxt->myDoc,
					    node);
	if (ret == 0) {
	    /*
	     * this element requires a full tree
	     */
	    node = xmlTextReaderExpand(reader);
	    if (node == NULL) {
printf("Expand failed !\n");
	        ret = -1;
	    } else {
		ret = xmlRelaxNGValidateFullElement(reader->rngValidCtxt,
						    reader->ctxt->myDoc,
						    node);
		reader->rngFullNode = node;
	    }
	}
	if (ret != 1)
	    reader->rngValidErrors++;
    }
#endif
}

/**
 * xmlTextReaderValidateCData:
 * @reader:  the xmlTextReaderPtr used
 * @data:  pointer to the CData
 * @len:  lenght of the CData block in bytes.
 *
 * Push some CData for validation
 */
static void
xmlTextReaderValidateCData(xmlTextReaderPtr reader,
                           const xmlChar *data, int len) {
#ifdef LIBXML_VALID_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
        (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
	reader->ctxt->valid &= xmlValidatePushCData(&reader->ctxt->vctxt,
	                                            data, len);
    }
#endif /* LIBXML_VALID_ENABLED */
#ifdef LIBXML_SCHEMAS_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
               (reader->rngValidCtxt != NULL)) {
	int ret;

	if (reader->rngFullNode != NULL) return;
	ret = xmlRelaxNGValidatePushCData(reader->rngValidCtxt, data, len);
	if (ret != 1)
	    reader->rngValidErrors++;
    }
#endif
}

/**
 * xmlTextReaderValidatePop:
 * @reader:  the xmlTextReaderPtr used
 *
 * Pop the current node from validation
 */
static void
xmlTextReaderValidatePop(xmlTextReaderPtr reader) {
    xmlNodePtr node = reader->node;

#ifdef LIBXML_VALID_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_DTD) &&
        (reader->ctxt != NULL) && (reader->ctxt->validate == 1)) {
	if ((node->ns == NULL) || (node->ns->prefix == NULL)) {
	    reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,
				    reader->ctxt->myDoc, node, node->name);
	} else {
	    /* TODO use the BuildQName interface */
	    xmlChar *qname;

	    qname = xmlStrdup(node->ns->prefix);
	    qname = xmlStrcat(qname, BAD_CAST ":");
	    qname = xmlStrcat(qname, node->name);
	    reader->ctxt->valid &= xmlValidatePopElement(&reader->ctxt->vctxt,
				    reader->ctxt->myDoc, node, qname);
	    if (qname != NULL)
		xmlFree(qname);
	}
    }
#endif /* LIBXML_VALID_ENABLED */
#ifdef LIBXML_SCHEMAS_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_RNG) &&
               (reader->rngValidCtxt != NULL)) {
	int ret;

	if (reader->rngFullNode != NULL) {
	    if (node == reader->rngFullNode) 
	        reader->rngFullNode = NULL;
	    return;
	}
	ret = xmlRelaxNGValidatePopElement(reader->rngValidCtxt,
	                                   reader->ctxt->myDoc,
					   node);
	if (ret != 1)
	    reader->rngValidErrors++;
    }
#endif
}

/**
 * xmlTextReaderValidateEntity:
 * @reader:  the xmlTextReaderPtr used
 *
 * Handle the validation when an entity reference is encountered and
 * entity substitution is not activated. As a result the parser interface
 * must walk through the entity and do the validation calls
 */
static void
xmlTextReaderValidateEntity(xmlTextReaderPtr reader) {
    xmlNodePtr oldnode = reader->node;
    xmlNodePtr node = reader->node;
    xmlParserCtxtPtr ctxt = reader->ctxt;

    do {
	if (node->type == XML_ENTITY_REF_NODE) {
	    /*
	     * Case where the underlying tree is not availble, lookup the entity
	     * and walk it.
	     */
	    if ((node->children == NULL) && (ctxt->sax != NULL) &&
		(ctxt->sax->getEntity != NULL)) {
		node->children = (xmlNodePtr) 
		    ctxt->sax->getEntity(ctxt, node->name);
	    }

	    if ((node->children != NULL) &&
		(node->children->type == XML_ENTITY_DECL) &&
		(node->children->children != NULL)) {
		xmlTextReaderEntPush(reader, node);
		node = node->children->children;
		continue;
	    } else {
		/*
		 * The error has probably be raised already.
		 */
		if (node == oldnode)
		    break;
		node = node->next;
	    }
#ifdef LIBXML_REGEXP_ENABLED
	} else if (node->type == XML_ELEMENT_NODE) {
	    reader->node = node;
	    xmlTextReaderValidatePush(reader);
	} else if ((node->type == XML_TEXT_NODE) ||
		   (node->type == XML_CDATA_SECTION_NODE)) {
            xmlTextReaderValidateCData(reader, node->content,
	                               xmlStrlen(node->content));
#endif
	}

	/*
	 * go to next node
	 */
	if (node->children != NULL) {
	    node = node->children;
	    continue;
	} else if (node->type == XML_ELEMENT_NODE) {
	    xmlTextReaderValidatePop(reader);
	}
	if (node->next != NULL) {
	    node = node->next;
	    continue;
	}
	do {
	    node = node->parent;
	    if (node->type == XML_ELEMENT_NODE) {
	        xmlNodePtr tmp;
		if (reader->entNr == 0) {
		    while ((tmp = node->last) != NULL) {
			if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
			    xmlUnlinkNode(tmp);
			    xmlTextReaderFreeNode(reader, tmp);
			} else
			    break;
		    }
		}
		reader->node = node;
		xmlTextReaderValidatePop(reader);
	    }
	    if ((node->type == XML_ENTITY_DECL) &&
		(reader->ent != NULL) && (reader->ent->children == node)) {
		node = xmlTextReaderEntPop(reader);
	    }
	    if (node == oldnode)
		break;
	    if (node->next != NULL) {
		node = node->next;
		break;
	    }
	} while ((node != NULL) && (node != oldnode));
    } while ((node != NULL) && (node != oldnode));
    reader->node = oldnode;
}
#endif /* LIBXML_REGEXP_ENABLED */


/**
 * xmlTextReaderGetSuccessor:
 * @cur:  the current node
 *
 * Get the successor of a node if available.
 *
 * Returns the successor node or NULL
 */
static xmlNodePtr
xmlTextReaderGetSuccessor(xmlNodePtr cur) {
    if (cur == NULL) return(NULL) ; /* ERROR */
    if (cur->next != NULL) return(cur->next) ;
    do {
        cur = cur->parent;
        if (cur == NULL) return(NULL);
        if (cur->next != NULL) return(cur->next);
    } while (cur != NULL);
    return(cur);
}

/**
 * xmlTextReaderDoExpand:
 * @reader:  the xmlTextReaderPtr used
 *
 * Makes sure that the current node is fully read as well as all its
 * descendant. It means the full DOM subtree must be available at the
 * end of the call.
 *
 * Returns 1 if the node was expanded successfully, 0 if there is no more
 *          nodes to read, or -1 in case of error
 */
static int
xmlTextReaderDoExpand(xmlTextReaderPtr reader) {
    int val;

    if ((reader == NULL) || (reader->node == NULL) || (reader->ctxt == NULL))
        return(-1);
    do {
	if (reader->ctxt->instate == XML_PARSER_EOF) return(1);

        if (xmlTextReaderGetSuccessor(reader->node) != NULL)
	    return(1);
	if (reader->ctxt->nodeNr < reader->depth)
	    return(1);
	if (reader->mode == XML_TEXTREADER_MODE_EOF)
	    return(1);
	val = xmlTextReaderPushData(reader);
	if (val < 0)
	    return(-1);
    } while(reader->mode != XML_TEXTREADER_MODE_EOF);
    return(1);
}

/**
 * xmlTextReaderCollectSiblings:
 * @node:    the first child
 *
 *  Traverse depth-first through all sibling nodes and their children
 *  nodes and concatenate their content. This is an auxiliary function
 *  to xmlTextReaderReadString.
 *
 *  Returns a string containing the content, or NULL in case of error.
 */
static xmlChar *
xmlTextReaderCollectSiblings(xmlNodePtr node)
{
    xmlBufferPtr buffer;
    xmlChar *ret;

    buffer = xmlBufferCreate();
    if (buffer == NULL)
       return NULL;

    for ( ; node != NULL; node = node->next) {
       switch (node->type) {
       case XML_TEXT_NODE:
       case XML_CDATA_SECTION_NODE:
           xmlBufferCat(buffer, node->content);
           break;
       case XML_ELEMENT_NODE:
           xmlBufferCat(buffer, xmlTextReaderCollectSiblings(node->children));
       default:
           break;
       }
    }
    ret = buffer->content;
    buffer->content = NULL;
    xmlBufferFree(buffer);
    return(ret);
}

/**
 * xmlTextReaderRead:
 * @reader:  the xmlTextReaderPtr used
 *
 *  Moves the position of the current instance to the next node in
 *  the stream, exposing its properties.
 *
 *  Returns 1 if the node was read successfully, 0 if there is no more
 *          nodes to read, or -1 in case of error
 */
int
xmlTextReaderRead(xmlTextReaderPtr reader) {
    int val, olddepth = 0;
    xmlTextReaderState oldstate = XML_TEXTREADER_START;
    xmlNodePtr oldnode = NULL;

   
    if (reader == NULL)
	return(-1);
    reader->curnode = NULL;
    if (reader->doc != NULL)
        return(xmlTextReaderReadTree(reader));
    if (reader->ctxt == NULL)
	return(-1);
    if (reader->ctxt->wellFormed != 1)
	return(-1);

#ifdef DEBUG_READER
    fprintf(stderr, "\nREAD ");
    DUMP_READER
#endif
    if (reader->mode == XML_TEXTREADER_MODE_INITIAL) {
	reader->mode = XML_TEXTREADER_MODE_INTERACTIVE;
	/*
	 * Initial state
	 */
	do {
	    val = xmlTextReaderPushData(reader);
	    if (val < 0)
		return(-1);
	} while ((reader->ctxt->node == NULL) &&
		 ((reader->mode != XML_TEXTREADER_MODE_EOF) &&
		  (reader->mode != XML_TEXTREADER_DONE)));
	if (reader->ctxt->node == NULL) {
	    if (reader->ctxt->myDoc != NULL) {
		reader->node = reader->ctxt->myDoc->children;
	    }
	    if (reader->node == NULL)
		return(-1);
	    reader->state = XML_TEXTREADER_ELEMENT;
	} else {
	    if (reader->ctxt->myDoc != NULL) {
		reader->node = reader->ctxt->myDoc->children;
	    }
	    if (reader->node == NULL)
		reader->node = reader->ctxt->nodeTab[0];
	    reader->state = XML_TEXTREADER_ELEMENT;
	}
	reader->depth = 0;
	reader->ctxt->parseMode = XML_PARSE_READER;
	goto node_found;
    }
    oldstate = reader->state;
    olddepth = reader->ctxt->nodeNr;
    oldnode = reader->node;

get_next_node:
    if (reader->node == NULL) {
	if (reader->mode == XML_TEXTREADER_DONE)
	    return(0);
	else
	    return(-1);
    }

    /*
     * If we are not backtracking on ancestors or examined nodes,
     * that the parser didn't finished or that we arent at the end
     * of stream, continue processing.
     */
    while ((reader->node != NULL) && (reader->node->next == NULL) &&
	   (reader->ctxt->nodeNr == olddepth) &&
           ((oldstate == XML_TEXTREADER_BACKTRACK) ||
            (reader->node->children == NULL) ||
	    (reader->node->type == XML_ENTITY_REF_NODE) ||
	    ((reader->node->children != NULL) &&
	     (reader->node->children->type == XML_TEXT_NODE) &&
	     (reader->node->children->next == NULL)) ||
	    (reader->node->type == XML_DTD_NODE) ||
	    (reader->node->type == XML_DOCUMENT_NODE) ||
	    (reader->node->type == XML_HTML_DOCUMENT_NODE)) &&
	   ((reader->ctxt->node == NULL) ||
	    (reader->ctxt->node == reader->node) ||
	    (reader->ctxt->node == reader->node->parent)) &&
	   (reader->ctxt->instate != XML_PARSER_EOF)) {
	val = xmlTextReaderPushData(reader);
	if (val < 0)
	    return(-1);
	if (reader->node == NULL)
	    goto node_end;
    }
    if (oldstate != XML_TEXTREADER_BACKTRACK) {
	if ((reader->node->children != NULL) &&
	    (reader->node->type != XML_ENTITY_REF_NODE) &&
	    (reader->node->type != XML_XINCLUDE_START) &&
	    (reader->node->type != XML_DTD_NODE)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -