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

📄 xmlreader.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
	    reader->node = reader->node->children;
	    reader->depth++;
	    reader->state = XML_TEXTREADER_ELEMENT;
	    goto node_found;
	}
    }
    if (reader->node->next != NULL) {
	if ((oldstate == XML_TEXTREADER_ELEMENT) &&
            (reader->node->type == XML_ELEMENT_NODE) &&
	    (reader->node->children == NULL) &&
	    ((reader->node->extra & NODE_IS_EMPTY) == 0)
#ifdef LIBXML_XINCLUDE_ENABLED
	    && (reader->in_xinclude <= 0)
#endif
	    ) {
	    reader->state = XML_TEXTREADER_END;
	    goto node_found;
	}
#ifdef LIBXML_REGEXP_ENABLED
	if ((reader->validate) &&
	    (reader->node->type == XML_ELEMENT_NODE))
	    xmlTextReaderValidatePop(reader);
#endif /* LIBXML_REGEXP_ENABLED */
        if ((reader->preserves > 0) &&
	    (reader->node->extra & NODE_IS_SPRESERVED))
	    reader->preserves--;
	reader->node = reader->node->next;
	reader->state = XML_TEXTREADER_ELEMENT;

	/*
	 * Cleanup of the old node
	 */
	if ((reader->preserves == 0) &&
#ifdef LIBXML_XINCLUDE_ENABLED
	    (reader->in_xinclude == 0) &&
#endif
	    (reader->entNr == 0) &&
	    (reader->node->prev != NULL) &&
            (reader->node->prev->type != XML_DTD_NODE) &&
	    (reader->entNr == 0)) {
	    xmlNodePtr tmp = reader->node->prev;
	    if ((tmp->extra & NODE_IS_PRESERVED) == 0) {
		xmlUnlinkNode(tmp);
		xmlTextReaderFreeNode(reader, tmp);
	    }
	}

	goto node_found;
    }
    if ((oldstate == XML_TEXTREADER_ELEMENT) &&
	(reader->node->type == XML_ELEMENT_NODE) &&
	(reader->node->children == NULL) &&
	((reader->node->extra & NODE_IS_EMPTY) == 0)) {;
	reader->state = XML_TEXTREADER_END;
	goto node_found;
    }
#ifdef LIBXML_REGEXP_ENABLED
    if ((reader->validate) && (reader->node->type == XML_ELEMENT_NODE))
	xmlTextReaderValidatePop(reader);
#endif /* LIBXML_REGEXP_ENABLED */
    if ((reader->preserves > 0) &&
	(reader->node->extra & NODE_IS_SPRESERVED))
	reader->preserves--;
    reader->node = reader->node->parent;
    if ((reader->node == NULL) ||
	(reader->node->type == XML_DOCUMENT_NODE) ||
#ifdef LIBXML_DOCB_ENABLED
	(reader->node->type == XML_DOCB_DOCUMENT_NODE) ||
#endif
	(reader->node->type == XML_HTML_DOCUMENT_NODE)) {
	if (reader->mode != XML_TEXTREADER_DONE) {
	    val = xmlParseChunk(reader->ctxt, "", 0, 1);
	    reader->mode = XML_TEXTREADER_DONE;
	    if (val != 0)
	        return(-1);
	}
	reader->node = NULL;
	reader->depth = -1;

	/*
	 * Cleanup of the old node
	 */
	if ((reader->preserves == 0) &&
#ifdef LIBXML_XINCLUDE_ENABLED
	    (reader->in_xinclude == 0) &&
#endif
	    (reader->entNr == 0) &&
	    (oldnode->type != XML_DTD_NODE) &&
	    ((oldnode->extra & NODE_IS_PRESERVED) == 0) &&
	    (reader->entNr == 0)) {
	    xmlUnlinkNode(oldnode);
	    xmlTextReaderFreeNode(reader, oldnode);
	}

	goto node_end;
    }
    if ((reader->preserves == 0) &&
#ifdef LIBXML_XINCLUDE_ENABLED
        (reader->in_xinclude == 0) &&
#endif
	(reader->entNr == 0) &&
        (reader->node->last != NULL) &&
        ((reader->node->last->extra & NODE_IS_PRESERVED) == 0)) {
	xmlNodePtr tmp = reader->node->last;
	xmlUnlinkNode(tmp);
	xmlTextReaderFreeNode(reader, tmp);
    }
    reader->depth--;
    reader->state = XML_TEXTREADER_BACKTRACK;

node_found:
    DUMP_READER

    /*
     * If we are in the middle of a piece of CDATA make sure it's finished
     */
    if ((reader->node != NULL) &&
        (reader->node->next == NULL) &&
        ((reader->node->type == XML_TEXT_NODE) ||
	 (reader->node->type == XML_CDATA_SECTION_NODE))) {
            if (xmlTextReaderExpand(reader) == NULL)
	        return -1;
    }

#ifdef LIBXML_XINCLUDE_ENABLED
    /*
     * Handle XInclude if asked for
     */
    if ((reader->xinclude) && (reader->node != NULL) &&
	(reader->node->type == XML_ELEMENT_NODE) &&
	(reader->node->ns != NULL) &&
	((xmlStrEqual(reader->node->ns->href, XINCLUDE_NS)) ||
	 (xmlStrEqual(reader->node->ns->href, XINCLUDE_OLD_NS)))) {
	if (reader->xincctxt == NULL) {
	    reader->xincctxt = xmlXIncludeNewContext(reader->ctxt->myDoc);
	    xmlXIncludeSetFlags(reader->xincctxt, 
	                        reader->parserFlags & (~XML_PARSE_NOXINCNODE));
	}
	/*
	 * expand that node and process it
	 */
	if (xmlTextReaderExpand(reader) == NULL)
	    return -1;
	xmlXIncludeProcessNode(reader->xincctxt, reader->node);
    }
    if (reader->node->type == XML_XINCLUDE_START) {
        reader->in_xinclude++;
	goto get_next_node;
    } 
    if (reader->node->type == XML_XINCLUDE_END) {
        reader->in_xinclude--;
	goto get_next_node;
    }
#endif
    /*
     * Handle entities enter and exit when in entity replacement mode
     */
    if ((reader->node != NULL) &&
	(reader->node->type == XML_ENTITY_REF_NODE) &&
	(reader->ctxt != NULL) && (reader->ctxt->replaceEntities == 1)) {
	/*
	 * Case where the underlying tree is not availble, lookup the entity
	 * and walk it.
	 */
	if ((reader->node->children == NULL) && (reader->ctxt->sax != NULL) &&
	    (reader->ctxt->sax->getEntity != NULL)) {
	    reader->node->children = (xmlNodePtr) 
		reader->ctxt->sax->getEntity(reader->ctxt, reader->node->name);
	}

	if ((reader->node->children != NULL) &&
	    (reader->node->children->type == XML_ENTITY_DECL) &&
	    (reader->node->children->children != NULL)) {
	    xmlTextReaderEntPush(reader, reader->node);
	    reader->node = reader->node->children->children;
	}
#ifdef LIBXML_REGEXP_ENABLED
    } else if ((reader->node != NULL) &&
	       (reader->node->type == XML_ENTITY_REF_NODE) &&
	       (reader->ctxt != NULL) && (reader->validate)) {
	xmlTextReaderValidateEntity(reader);
#endif /* LIBXML_REGEXP_ENABLED */
    }
    if ((reader->node != NULL) &&
	(reader->node->type == XML_ENTITY_DECL) &&
	(reader->ent != NULL) && (reader->ent->children == reader->node)) {
	reader->node = xmlTextReaderEntPop(reader);
	reader->depth++;
        goto get_next_node;
    }
#ifdef LIBXML_REGEXP_ENABLED
    if ((reader->validate) && (reader->node != NULL)) {
	xmlNodePtr node = reader->node;

	if ((node->type == XML_ELEMENT_NODE) && 
            ((reader->state != XML_TEXTREADER_END) &&
	     (reader->state != XML_TEXTREADER_BACKTRACK))) {
	    xmlTextReaderValidatePush(reader);
	} else if ((node->type == XML_TEXT_NODE) ||
		   (node->type == XML_CDATA_SECTION_NODE)) {
            xmlTextReaderValidateCData(reader, node->content,
	                               xmlStrlen(node->content));
	}
    }
#endif /* LIBXML_REGEXP_ENABLED */
#ifdef LIBXML_PATTERN_ENABLED
    if ((reader->patternNr > 0) && (reader->state != XML_TEXTREADER_END) &&
        (reader->state != XML_TEXTREADER_BACKTRACK)) {
        int i;
	for (i = 0;i < reader->patternNr;i++) {
	     if (xmlPatternMatch(reader->patternTab[i], reader->node) == 1) {
	         xmlTextReaderPreserve(reader);
		 break;
             }
	}
    }
#endif /* LIBXML_PATTERN_ENABLED */
#ifdef LIBXML_SCHEMAS_ENABLED
    if ((reader->validate == XML_TEXTREADER_VALIDATE_XSD) &&
        (reader->xsdValidErrors == 0) && 
	(reader->xsdValidCtxt != NULL)) {
	reader->xsdValidErrors = !xmlSchemaIsValid(reader->xsdValidCtxt);
    }
#endif /* LIBXML_PATTERN_ENABLED */
    return(1);
node_end:
    reader->mode = XML_TEXTREADER_DONE;
    return(0);
}

/**
 * xmlTextReaderReadState:
 * @reader:  the xmlTextReaderPtr used
 *
 * Gets the read state of the reader.
 *
 * Returns the state value, or -1 in case of error
 */
int
xmlTextReaderReadState(xmlTextReaderPtr reader) {
    if (reader == NULL)
	return(-1);
    return(reader->mode);
}

/**
 * xmlTextReaderExpand:
 * @reader:  the xmlTextReaderPtr used
 *
 * Reads the contents of the current node and the full subtree. It then makes
 * the subtree available until the next xmlTextReaderRead() call
 *
 * Returns a node pointer valid until the next xmlTextReaderRead() call
 *         or NULL in case of error.
 */
xmlNodePtr
xmlTextReaderExpand(xmlTextReaderPtr reader) {
    if ((reader == NULL) || (reader->node == NULL))
        return(NULL);
    if (reader->doc != NULL)
        return(reader->node);
    if (reader->ctxt == NULL)
        return(NULL);
    if (xmlTextReaderDoExpand(reader) < 0)
        return(NULL);
    return(reader->node);
}

/**
 * xmlTextReaderNext:
 * @reader:  the xmlTextReaderPtr used
 *
 * Skip to the node following the current one in document order while
 * avoiding the subtree if any.
 *
 * Returns 1 if the node was read successfully, 0 if there is no more
 *          nodes to read, or -1 in case of error
 */
int
xmlTextReaderNext(xmlTextReaderPtr reader) {
    int ret;
    xmlNodePtr cur;

    if (reader == NULL)
	return(-1);
    if (reader->doc != NULL)
        return(xmlTextReaderNextTree(reader));
    cur = reader->node;
    if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
        return(xmlTextReaderRead(reader));
    if (reader->state == XML_TEXTREADER_END || reader->state == XML_TEXTREADER_BACKTRACK)
        return(xmlTextReaderRead(reader));
    if (cur->extra & NODE_IS_EMPTY)
        return(xmlTextReaderRead(reader));
    do {
        ret = xmlTextReaderRead(reader);
	if (ret != 1)
	    return(ret);
    } while (reader->node != cur);
    return(xmlTextReaderRead(reader));
}

/**
 * xmlTextReaderReadInnerXml:
 * @reader:  the xmlTextReaderPtr used
 *
 * Reads the contents of the current node, including child nodes and markup.
 *
 * Returns a string containing the XML content, or NULL if the current node
 *         is neither an element nor attribute, or has no child nodes. The 
 *         string must be deallocated by the caller.
 */
xmlChar *
xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
{
    xmlChar *resbuf;
    xmlNodePtr node, cur_node;
    xmlBufferPtr buff, buff2;
    xmlDocPtr doc;

    if (xmlTextReaderExpand(reader) == NULL) {
        return NULL;
    }
    doc = reader->doc;
    buff = xmlBufferCreate();
    for (cur_node = reader->node->children; cur_node != NULL;
         cur_node = cur_node->next) {
        node = xmlDocCopyNode(cur_node, doc, 1);
        buff2 = xmlBufferCreate();
        if (xmlNodeDump(buff2, doc, node, 0, 0) == -1) {
            xmlFreeNode(node);
            xmlBufferFree(buff2);
            xmlBufferFree(buff);
            return NULL;
        }
        xmlBufferCat(buff, buff2->content);
        xmlFreeNode(node);
        xmlBufferFree(buff2);
    }
    resbuf = buff->content;
    return resbuf;
}

/**
 * xmlTextReaderReadOuterXml:
 * @reader:  the xmlTextReaderPtr used
 *
 * Reads the contents of the current node, including child nodes and markup.
 *
 * Returns a string containing the XML content, or NULL if the current node
 *         is neither an element nor attribute, or has no child nodes. The 
 *         string must be deallocated by the caller.
 */
xmlChar *
xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
{
    xmlChar *resbuf;
    xmlNodePtr node;
    xmlBufferPtr buff;
    xmlDocPtr doc;

    node = reader->node;
    doc = reader->doc;
    if (xmlTextReaderExpand(reader) == NULL) {
        return NULL;
    }
    node = xmlDocCopyNode(node, doc, 1);
    buff = xmlBufferCreate();
    if (xmlNodeDump(buff, doc, node, 0, 0) == -1) {
        xmlFreeNode(node);
        xmlBufferFree(buff);
        return NULL;
    }

    resbuf = buff->content;
    buff->content = NULL;

    xmlFreeNode(node);
    xmlBufferFree(buff);
    return resbuf;
}

/**
 * xmlTextReaderReadString:
 * @reader:  the xmlTextReaderPtr used
 *
 * Reads the contents of an element or a text node as a string.
 *
 * Returns a string containing the contents of the Element or Text node,
 *         or NULL if the reader is positioned on any other type of node.
 *         The string must be deallocated by the caller.
 */
xmlChar *
xmlTextReaderReadString(xmlTextReaderPtr reader)
{
    xmlNodePtr node;

    if ((reader == NULL) || (reader->node == NULL))
       return(NULL);

    node = (reader->curnode != NULL) ? reader->curnode : reader->node;
    switch (node->type) {
    case XML_TEXT_NODE:
       if (node->content != NULL)
           return(xmlStrdup(node->content));
       break;
    case XML_ELEMENT_NODE:
	if (xmlTextReaderDoExpand(reader) != -1) {
	    return xmlTextReaderCollectSiblings(node->children);
	}
    case XML_ATTRIBUTE_NODE:
	TODO
	break;
    default:
       break;
    }
    return(NULL);
}

#if 0
/**
 * xmlTextReaderReadBase64:
 * @reader:  the xmlTextReaderPtr used
 * @array:  a byte array to store the content.
 * @offset:  the zero-based index into array where the method should
 *           begin to write.
 * @len:  the number of bytes to write.
 *
 * Reads and decodes the Base64 encoded contents of an element and
 * stores the result in a byte buffer.
 *
 * Returns the number of bytes written to array, or zero if the current
 *         instance is not positioned on an element or -1 in case of error.
 */
int
xmlTextReaderReadBase64(xmlTextReaderPtr reader,
                        unsigned char *array ATTRIBUTE_UNUSED,
	                int offset ATTRIBUTE_UNUSED,
			int len ATTRIBUTE_UNUSED) {

⌨️ 快捷键说明

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