📄 xmlreader.c
字号:
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_MODE_EOF) { val = xmlParseChunk(reader->ctxt, "", 0, 1); reader->state = 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 != NULL) && (reader->node->type == XML_XINCLUDE_START)) { reader->in_xinclude++; goto get_next_node; } if ((reader->node != NULL) && (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->state = 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 */intxmlTextReaderReadState(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. */xmlNodePtrxmlTextReaderExpand(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 */intxmlTextReaderNext(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));}#ifdef LIBXML_WRITER_ENABLED/** * 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; buff->content = NULL; xmlBufferFree(buff); return resbuf;}#endif#ifdef LIBXML_WRITER_ENABLED/** * 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;}#endif/** * 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. */intxmlTextReaderReadBase64(xmlTextReaderPtr reader, unsigned char *array ATTRIBUTE_UNUSED, int offset ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED) { if ((reader == NULL) || (reader->ctxt == NULL)) return(-1); if (reader->ctxt->wellFormed != 1) return(-1); if ((reader->node == NULL) || (reader->node->type == XML_ELEMENT_NODE)) return(0); TODO return(0);}/** * xmlTextReaderReadBinHex: * @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 BinHex 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. */intxmlTextReaderReadBinHex(xmlTextReaderPtr reader, unsigned char *array ATTRIBUTE_UNUSED, int offset ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED) { if ((reader == NULL) || (reader->ctxt == NULL)) return(-1); if (reader->ctxt->wellFormed != 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -