* xmlXPathNodeSetFilter: * @ctxt: the XPath Parser context * @set: the node set to filter * @filterOpIndex: the index of the predicate/filter op * @minPos: minimum position in the filtered set (1-based) * @maxPos: maximum position in the filtered set (1-based) * @hasNsNodes: true if the node set may contain namespace nodes * * Filter a node set, keeping only nodes for which the predicate
| 10468 | * filtered result. |
| 10469 | */ |
| 10470 | static void |
| 10471 | xmlXPathNodeSetFilter(xmlXPathParserContextPtr ctxt, |
| 10472 | xmlNodeSetPtr set, |
| 10473 | int filterOpIndex, |
| 10474 | int minPos, int maxPos, |
| 10475 | int hasNsNodes) |
| 10476 | { |
| 10477 | xmlXPathContextPtr xpctxt; |
| 10478 | xmlNodePtr oldnode; |
| 10479 | xmlDocPtr olddoc; |
| 10480 | xmlXPathStepOpPtr filterOp; |
| 10481 | int oldcs, oldpp; |
| 10482 | int i, j, pos; |
| 10483 | |
| 10484 | if ((set == NULL) || (set->nodeNr == 0)) |
| 10485 | return; |
| 10486 | |
| 10487 | /* |
| 10488 | * Check if the node set contains a sufficient number of nodes for |
| 10489 | * the requested range. |
| 10490 | */ |
| 10491 | if (set->nodeNr < minPos) { |
| 10492 | xmlXPathNodeSetClear(set, hasNsNodes); |
| 10493 | return; |
| 10494 | } |
| 10495 | |
| 10496 | xpctxt = ctxt->context; |
| 10497 | oldnode = xpctxt->node; |
| 10498 | olddoc = xpctxt->doc; |
| 10499 | oldcs = xpctxt->contextSize; |
| 10500 | oldpp = xpctxt->proximityPosition; |
| 10501 | filterOp = &ctxt->comp->steps[filterOpIndex]; |
| 10502 | |
| 10503 | xpctxt->contextSize = set->nodeNr; |
| 10504 | |
| 10505 | for (i = 0, j = 0, pos = 1; i < set->nodeNr; i++) { |
| 10506 | xmlNodePtr node = set->nodeTab[i]; |
| 10507 | int res; |
| 10508 | |
| 10509 | xpctxt->node = node; |
| 10510 | xpctxt->proximityPosition = i + 1; |
| 10511 | |
| 10512 | /* |
| 10513 | * Also set the xpath document in case things like |
| 10514 | * key() are evaluated in the predicate. |
| 10515 | * |
| 10516 | * TODO: Get real doc for namespace nodes. |
| 10517 | */ |
| 10518 | if ((node->type != XML_NAMESPACE_DECL) && |
| 10519 | (node->doc != NULL)) |
| 10520 | xpctxt->doc = node->doc; |
| 10521 | |
| 10522 | res = xmlXPathCompOpEvalToBoolean(ctxt, filterOp, 1); |
| 10523 | |
| 10524 | if (ctxt->error != XPATH_EXPRESSION_OK) |
| 10525 | break; |
| 10526 | if (res < 0) { |
| 10527 | /* Shouldn't happen */ |
no test coverage detected