* xmlXPathDistinctSorted: * @nodes: a node-set, sorted by document order * * Implements the EXSLT - Sets distinct() function: * node-set set:distinct (node-set) * * Returns a subset of the nodes contained in @nodes, or @nodes if * it is empty */
| 3584 | * it is empty |
| 3585 | */ |
| 3586 | xmlNodeSetPtr |
| 3587 | xmlXPathDistinctSorted (xmlNodeSetPtr nodes) { |
| 3588 | xmlNodeSetPtr ret; |
| 3589 | xmlHashTablePtr hash; |
| 3590 | int i, l; |
| 3591 | xmlChar * strval; |
| 3592 | xmlNodePtr cur; |
| 3593 | |
| 3594 | if (xmlXPathNodeSetIsEmpty(nodes)) |
| 3595 | return(nodes); |
| 3596 | |
| 3597 | ret = xmlXPathNodeSetCreate(NULL); |
| 3598 | if (ret == NULL) |
| 3599 | return(ret); |
| 3600 | l = xmlXPathNodeSetGetLength(nodes); |
| 3601 | hash = xmlHashCreate (l); |
| 3602 | for (i = 0; i < l; i++) { |
| 3603 | cur = xmlXPathNodeSetItem(nodes, i); |
| 3604 | strval = xmlXPathCastNodeToString(cur); |
| 3605 | if (xmlHashLookup(hash, strval) == NULL) { |
| 3606 | if (xmlHashAddEntry(hash, strval, strval) < 0) { |
| 3607 | xmlFree(strval); |
| 3608 | goto error; |
| 3609 | } |
| 3610 | if (xmlXPathNodeSetAddUnique(ret, cur) < 0) |
| 3611 | goto error; |
| 3612 | } else { |
| 3613 | xmlFree(strval); |
| 3614 | } |
| 3615 | } |
| 3616 | xmlHashFree(hash, xmlHashDefaultDeallocator); |
| 3617 | return(ret); |
| 3618 | |
| 3619 | error: |
| 3620 | xmlHashFree(hash, xmlHashDefaultDeallocator); |
| 3621 | xmlXPathFreeNodeSet(ret); |
| 3622 | return(NULL); |
| 3623 | } |
| 3624 | |
| 3625 | /** |
| 3626 | * xmlXPathDistinct: |
no test coverage detected