📄 xpointer.c.svn-base
字号:
tmp = xmlCopyNode(cur, 1); list = tmp; parent = NULL; last = tmp; } } else { tmp = NULL; switch (cur->type) { case XML_DTD_NODE: case XML_ELEMENT_DECL: case XML_ATTRIBUTE_DECL: case XML_ENTITY_NODE: /* Do not copy DTD informations */ break; case XML_ENTITY_DECL: TODO /* handle crossing entities -> stack needed */ break; case XML_XINCLUDE_START: case XML_XINCLUDE_END: /* don't consider it part of the tree content */ break; case XML_ATTRIBUTE_NODE: /* Humm, should not happen ! */ STRANGE break; default: tmp = xmlCopyNode(cur, 1); break; } if (tmp != NULL) { if ((list == NULL) || ((last == NULL) && (parent == NULL))) { STRANGE return(NULL); } if (last != NULL) xmlAddNextSibling(last, tmp); else { xmlAddChild(parent, tmp); last = tmp; } } } /* * Skip to next node in document order */ if ((list == NULL) || ((last == NULL) && (parent == NULL))) { STRANGE return(NULL); } cur = xmlXPtrAdvanceNode(cur, NULL); } return(list);}/** * xmlXPtrBuildNodeList: * @obj: the XPointer result from the evaluation. * * Build a node list tree copy of the XPointer result. * This will drop Attributes and Namespace declarations. * * Returns an xmlNodePtr list or NULL. * the caller has to free the node tree. */xmlNodePtrxmlXPtrBuildNodeList(xmlXPathObjectPtr obj) { xmlNodePtr list = NULL, last = NULL; int i; if (obj == NULL) return(NULL); switch (obj->type) { case XPATH_NODESET: { xmlNodeSetPtr set = obj->nodesetval; if (set == NULL) return(NULL); for (i = 0;i < set->nodeNr;i++) { if (set->nodeTab[i] == NULL) continue; switch (set->nodeTab[i]->type) { case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: case XML_ELEMENT_NODE: case XML_ENTITY_REF_NODE: case XML_ENTITY_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: case XML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE:#ifdef LIBXML_DOCB_ENABLED case XML_DOCB_DOCUMENT_NODE:#endif case XML_XINCLUDE_START: case XML_XINCLUDE_END: break; case XML_ATTRIBUTE_NODE: case XML_NAMESPACE_DECL: case XML_DOCUMENT_TYPE_NODE: case XML_DOCUMENT_FRAG_NODE: case XML_NOTATION_NODE: case XML_DTD_NODE: case XML_ELEMENT_DECL: case XML_ATTRIBUTE_DECL: case XML_ENTITY_DECL: continue; /* for */ } if (last == NULL) list = last = xmlCopyNode(set->nodeTab[i], 1); else { xmlAddNextSibling(last, xmlCopyNode(set->nodeTab[i], 1)); if (last->next != NULL) last = last->next; } } break; } case XPATH_LOCATIONSET: { xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user; if (set == NULL) return(NULL); for (i = 0;i < set->locNr;i++) { if (last == NULL) list = last = xmlXPtrBuildNodeList(set->locTab[i]); else xmlAddNextSibling(last, xmlXPtrBuildNodeList(set->locTab[i])); if (last != NULL) { while (last->next != NULL) last = last->next; } } break; } case XPATH_RANGE: return(xmlXPtrBuildRangeNodeList(obj)); case XPATH_POINT: return(xmlCopyNode(obj->user, 0)); default: break; } return(list);}/************************************************************************ * * * XPointer functions * * * ************************************************************************//** * xmlXPtrNbLocChildren: * @node: an xmlNodePtr * * Count the number of location children of @node or the length of the * string value in case of text/PI/Comments nodes * * Returns the number of location children */static intxmlXPtrNbLocChildren(xmlNodePtr node) { int ret = 0; if (node == NULL) return(-1); switch (node->type) { case XML_HTML_DOCUMENT_NODE: case XML_DOCUMENT_NODE: case XML_ELEMENT_NODE: node = node->children; while (node != NULL) { if (node->type == XML_ELEMENT_NODE) ret++; node = node->next; } break; case XML_ATTRIBUTE_NODE: return(-1); case XML_PI_NODE: case XML_COMMENT_NODE: case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: case XML_ENTITY_REF_NODE: ret = xmlStrlen(node->content); break; default: return(-1); } return(ret);}/** * xmlXPtrHereFunction: * @ctxt: the XPointer Parser context * @nargs: the number of args * * Function implementing here() operation * as described in 5.4.3 */voidxmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs) { CHECK_ARITY(0); if (ctxt->context->here == NULL) XP_ERROR(XPTR_SYNTAX_ERROR); valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->here, NULL));}/** * xmlXPtrOriginFunction: * @ctxt: the XPointer Parser context * @nargs: the number of args * * Function implementing origin() operation * as described in 5.4.3 */voidxmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs) { CHECK_ARITY(0); if (ctxt->context->origin == NULL) XP_ERROR(XPTR_SYNTAX_ERROR); valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->origin, NULL));}/** * xmlXPtrStartPointFunction: * @ctxt: the XPointer Parser context * @nargs: the number of args * * Function implementing start-point() operation * as described in 5.4.3 * ---------------- * location-set start-point(location-set) * * For each location x in the argument location-set, start-point adds a * location of type point to the result location-set. That point represents * the start point of location x and is determined by the following rules: * * - If x is of type point, the start point is x. * - If x is of type range, the start point is the start point of x. * - If x is of type root, element, text, comment, or processing instruction, * - the container node of the start point is x and the index is 0. * - If x is of type attribute or namespace, the function must signal a * syntax error. * ---------------- * */voidxmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathObjectPtr tmp, obj, point; xmlLocationSetPtr newset = NULL; xmlLocationSetPtr oldset = NULL; CHECK_ARITY(1); if ((ctxt->value == NULL) || ((ctxt->value->type != XPATH_LOCATIONSET) && (ctxt->value->type != XPATH_NODESET))) XP_ERROR(XPATH_INVALID_TYPE) obj = valuePop(ctxt); if (obj->type == XPATH_NODESET) { /* * First convert to a location set */ tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval); xmlXPathFreeObject(obj); obj = tmp; } newset = xmlXPtrLocationSetCreate(NULL); if (newset == NULL) { xmlXPathFreeObject(obj); XP_ERROR(XPATH_MEMORY_ERROR); } oldset = (xmlLocationSetPtr) obj->user; if (oldset != NULL) { int i; for (i = 0; i < oldset->locNr; i++) { tmp = oldset->locTab[i]; if (tmp == NULL) continue; point = NULL; switch (tmp->type) { case XPATH_POINT: point = xmlXPtrNewPoint(tmp->user, tmp->index); break; case XPATH_RANGE: { xmlNodePtr node = tmp->user; if (node != NULL) { if (node->type == XML_ATTRIBUTE_NODE) { /* TODO: Namespace Nodes ??? */ xmlXPathFreeObject(obj); xmlXPtrFreeLocationSet(newset); XP_ERROR(XPTR_SYNTAX_ERROR); } point = xmlXPtrNewPoint(node, tmp->index); } break; } default: /*** Should we raise an error ? xmlXPathFreeObject(obj); xmlXPathFreeObject(newset); XP_ERROR(XPATH_INVALID_TYPE) ***/ break; } if (point != NULL) xmlXPtrLocationSetAdd(newset, point); } } xmlXPathFreeObject(obj); valuePush(ctxt, xmlXPtrWrapLocationSet(newset));}/** * xmlXPtrEndPointFunction: * @ctxt: the XPointer Parser context * @nargs: the number of args * * Function implementing end-point() operation * as described in 5.4.3 * ---------------------------- * location-set end-point(location-set) * * For each location x in the argument location-set, end-point adds a * location of type point to the result location-set. That point represents * the end point of location x and is determined by the following rules: * * - If x is of type point, the resulting point is x. * - If x is of type range, the resulting point is the end point of x. * - If x is of type root or element, the container node of the resulting * point is x and the index is the number of location children of x. * - If x is of type text, comment, or processing instruction, the container * node of the resulting point is x and the index is the length of the * string-value of x. * - If x is of type attribute or namespace, the function must signal a * syntax error. * ---------------------------- */voidxmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathObjectPtr tmp, obj, point; xmlLocationSetPtr newset = NULL; xmlLocationSetPtr oldset = NULL; CHECK_ARITY(1); if ((ctxt->value == NULL) || ((ctxt->value->type != XPATH_LOCATIONSET) && (ctxt->value->type != XPATH_NODESET))) XP_ERROR(XPATH_INVALID_TYPE) obj = valuePop(ctxt); if (obj->type == XPATH_NODESET) { /* * First convert to a location set */ tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval); xmlXPathFreeObject(obj); obj = tmp; } newset = xmlXPtrLocationSetCreate(NULL); oldset = (xmlLocationSetPtr) obj->user; if (oldset != NULL) { int i; for (i = 0; i < oldset->locNr; i++) { tmp = oldset->locTab[i]; if (tmp == NULL) continue; point = NULL; switch (tmp->type) { case XPATH_POINT: point = xmlXPtrNewPoint(tmp->user, tmp->index); break; case XPATH_RANGE: { xmlNodePtr node = tmp->user2; if (node != NULL) { if (node->type == XML_ATTRIBUTE_NODE) { /* TODO: Namespace Nodes ??? */ xmlXPathFreeObject(obj); xmlXPtrFreeLocationSet(newset); XP_ERROR(XPTR_SYNTAX_ERROR); } point = xmlXPtrNewPoint(node, tmp->index2); } else if (tmp->user == NULL) { point = xmlXPtrNewPoint(node, xmlXPtrNbLocChildren(node)); } break; } default: /*** Should we raise an error ? xmlXPathFreeObject(obj); xmlXPathFreeObject(newset); XP_ERROR(XPATH_INVALID_TYPE) ***/ break; } if (point != NULL) xmlXPtrLocationSetAdd(newset, point); } } xmlXPathFreeObject(obj); valuePush(ctxt, xmlXPtrWrapLocationSet(newset));}/** * xmlXPtrCoveringRange: * @ctxt: the XPointer Parser context * @loc: the location for which the covering range must be computed * * A covering range is a range that wholly encompasses a location * Section 5.3.3. Covering Ranges for All Location Types * http://www.w3.org/TR/xptr#N2267 * * Returns a new location or NULL in case of error */static xmlXPathObjectPtrxmlXPtrCoveringRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) { if (loc == NULL) return(NULL); if ((ctxt == NULL) || (ctxt->context == NULL) || (ctxt->context->doc == NULL)) return(NULL); switch (loc->type) { case XPATH_POINT: return(xmlXPtrNewRange(loc->user, loc->index, loc->user, loc->index)); case XPATH_RANGE: if (loc->user2 != NULL) { return(xmlXPtrNewRange(loc->user, loc->index, loc->user2, loc->index2)); } else { xmlNodePtr node = (xmlNodePtr) loc->user; if (node == (xmlNodePtr) ctxt->context->doc) { return(xmlXPtrNewRange(node, 0, node, xmlXPtrGetArity(node))); } else { switch (node->type) { case XML_ATTRIBUTE_NODE: /* !!! our model is slightly different than XPath */ return(xmlXPtrNewRange(node, 0, node, xmlXPtrGetArity(node))); case XML_ELEMENT_NODE: case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: case XML_ENTITY_REF_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: case XML_DOCUMENT_NODE: case XML_NOTATION_NODE: case XML_HTML_DOCUMENT_NODE: { int indx = xmlXPtrGetIndex(node); node = node->parent; return(xmlXPtrNewRange(node, indx - 1, node, indx + 1)); } default: return(NULL); } } } default: TODO /* missed one case ??? */ } return(NULL);}/** * xmlXPtrRangeFunction: * @ctxt: the XPointer Parser context * @nargs: the number of args * * Function implementing the range() function 5.4.3 * location-set range(location-set ) * * The range function returns ranges covering the locations in * the argument location-set. For each location x in the argument * location-set, a range location representing the covering range of * x is added to the result location-set. */voidxmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) { int i; xmlXPathObjectPtr set; xmlLocationSetPtr oldset; xmlLocationSetPtr newset; CHECK_ARITY(1); if ((ctxt->value == NULL) || ((ctxt->value->type != XPATH_LOCATIONSET) && (ctxt->value->type != XPATH_NODESET))) XP_ERROR(XPATH_INVALID_TYPE) set = valuePop(ctxt); if (set->type == XPATH_NODESET) { xmlXPathObjectPtr tmp; /* * First convert to a location set */ tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval); xmlXPathFreeObject(set); set = tmp; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -