📄 xpath.c
字号:
#define AXIS_FOLLOWING 7#define AXIS_FOLLOWING_SIBLING 8#define AXIS_NAMESPACE 9#define AXIS_PARENT 10#define AXIS_PRECEDING 11#define AXIS_PRECEDING_SIBLING 12#define AXIS_SELF 13/* * A traversal function enumerates nodes along an axis. * Initially it must be called with NULL, and it indicates * termination on the axis by returning NULL. */typedef xmlNodePtr (*xmlXPathTraversalFunction) (xmlXPathParserContextPtr ctxt, xmlNodePtr cur);/** * mlXPathNextSelf: * @ctxt: the XPath Parser context * @cur: the current node in the traversal * * Traversal function for the "self" direction * he self axis contains just the context node itself * * Returns the next element following that axis */xmlNodePtrxmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if (cur == NULL) return(ctxt->context->node); return(NULL);}/** * mlXPathNextChild: * @ctxt: the XPath Parser context * @cur: the current node in the traversal * * Traversal function for the "child" direction * The child axis contains the children of the context node in document order. * * Returns the next element following that axis */xmlNodePtrxmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if (cur == NULL) { if (ctxt->context->node == NULL) return(NULL); switch (ctxt->context->node->type) { case XML_ELEMENT_NODE: case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: case XML_ENTITY_REF_NODE: case XML_ENTITY_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: case XML_NOTATION_NODE: case XML_DTD_NODE: return(ctxt->context->node->children); case XML_DOCUMENT_NODE: case XML_DOCUMENT_TYPE_NODE: case XML_DOCUMENT_FRAG_NODE: case XML_HTML_DOCUMENT_NODE: return(((xmlDocPtr) ctxt->context->node)->children); case XML_ELEMENT_DECL: case XML_ATTRIBUTE_DECL: case XML_ENTITY_DECL: case XML_ATTRIBUTE_NODE: return(NULL); } return(NULL); } if ((cur->type == XML_DOCUMENT_NODE) || (cur->type == XML_HTML_DOCUMENT_NODE)) return(NULL); return(cur->next);}/** * mlXPathNextDescendant: * @ctxt: the XPath Parser context * @cur: the current node in the traversal * * Traversal function for the "descendant" direction * the descendant axis contains the descendants of the context node in document * order; a descendant is a child or a child of a child and so on. * * Returns the next element following that axis */xmlNodePtrxmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if (cur == NULL) { if (ctxt->context->node == NULL) return(NULL); if (ctxt->context->node->type == XML_ATTRIBUTE_NODE) return(NULL); if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc) return(ctxt->context->doc->children); return(ctxt->context->node->children); } if (cur->children != NULL) return(cur->children); if (cur->next != NULL) return(cur->next); do { cur = cur->parent; if (cur == NULL) return(NULL); if (cur == ctxt->context->node) return(NULL); if (cur->next != NULL) { cur = cur->next; return(cur); } } while (cur != NULL); return(cur);}/** * mlXPathNextDescendantOrSelf: * @ctxt: the XPath Parser context * @cur: the current node in the traversal * * Traversal function for the "descendant-or-self" direction * the descendant-or-self axis contains the context node and the descendants * of the context node in document order; thus the context node is the first * node on the axis, and the first child of the context node is the second node * on the axis * * Returns the next element following that axis */xmlNodePtrxmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if (cur == NULL) { if (ctxt->context->node == NULL) return(NULL); if (ctxt->context->node->type == XML_ATTRIBUTE_NODE) return(NULL); return(ctxt->context->node); } return(xmlXPathNextDescendant(ctxt, cur));}/** * xmlXPathNextParent: * @ctxt: the XPath Parser context * @cur: the current node in the traversal * * Traversal function for the "parent" direction * The parent axis contains the parent of the context node, if there is one. * * Returns the next element following that axis */xmlNodePtrxmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { /* * the parent of an attribute or namespace node is the element * to which the attribute or namespace node is attached * Namespace handling !!! */ if (cur == NULL) { if (ctxt->context->node == NULL) return(NULL); switch (ctxt->context->node->type) { case XML_ELEMENT_NODE: case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: case XML_ENTITY_REF_NODE: case XML_ENTITY_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: case XML_NOTATION_NODE: case XML_DTD_NODE: case XML_ELEMENT_DECL: case XML_ATTRIBUTE_DECL: case XML_ENTITY_DECL: if (ctxt->context->node->parent == NULL) return((xmlNodePtr) ctxt->context->doc); return(ctxt->context->node->parent); case XML_ATTRIBUTE_NODE: { xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node; return(att->parent); } case XML_DOCUMENT_NODE: case XML_DOCUMENT_TYPE_NODE: case XML_DOCUMENT_FRAG_NODE: case XML_HTML_DOCUMENT_NODE: return(NULL); } } return(NULL);}/** * xmlXPathNextAncestor: * @ctxt: the XPath Parser context * @cur: the current node in the traversal * * Traversal function for the "ancestor" direction * the ancestor axis contains the ancestors of the context node; the ancestors * of the context node consist of the parent of context node and the parent's * parent and so on; the nodes are ordered in reverse document order; thus the * parent is the first node on the axis, and the parent's parent is the second * node on the axis * * Returns the next element following that axis */xmlNodePtrxmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { /* * the parent of an attribute or namespace node is the element * to which the attribute or namespace node is attached * !!!!!!!!!!!!! */ if (cur == NULL) { if (ctxt->context->node == NULL) return(NULL); switch (ctxt->context->node->type) { case XML_ELEMENT_NODE: case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: case XML_ENTITY_REF_NODE: case XML_ENTITY_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: case XML_DTD_NODE: case XML_ELEMENT_DECL: case XML_ATTRIBUTE_DECL: case XML_ENTITY_DECL: case XML_NOTATION_NODE: if (ctxt->context->node->parent == NULL) return((xmlNodePtr) ctxt->context->doc); return(ctxt->context->node->parent); case XML_ATTRIBUTE_NODE: { xmlAttrPtr cur = (xmlAttrPtr) ctxt->context->node; return(cur->parent); } case XML_DOCUMENT_NODE: case XML_DOCUMENT_TYPE_NODE: case XML_DOCUMENT_FRAG_NODE: case XML_HTML_DOCUMENT_NODE: return(NULL); } return(NULL); } if (cur == ctxt->context->doc->children) return((xmlNodePtr) ctxt->context->doc); if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL); switch (cur->type) { case XML_ELEMENT_NODE: case XML_TEXT_NODE: case XML_CDATA_SECTION_NODE: case XML_ENTITY_REF_NODE: case XML_ENTITY_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: case XML_NOTATION_NODE: case XML_DTD_NODE: case XML_ELEMENT_DECL: case XML_ATTRIBUTE_DECL: case XML_ENTITY_DECL: return(cur->parent); case XML_ATTRIBUTE_NODE: { xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node; return(att->parent); } case XML_DOCUMENT_NODE: case XML_DOCUMENT_TYPE_NODE: case XML_DOCUMENT_FRAG_NODE: case XML_HTML_DOCUMENT_NODE: return(NULL); } return(NULL);}/** * xmlXPathNextAncestorOrSelf: * @ctxt: the XPath Parser context * @cur: the current node in the traversal * * Traversal function for the "ancestor-or-self" direction * he ancestor-or-self axis contains the context node and ancestors of * the context node in reverse document order; thus the context node is * the first node on the axis, and the context node's parent the second; * parent here is defined the same as with the parent axis. * * Returns the next element following that axis */xmlNodePtrxmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if (cur == NULL) return(ctxt->context->node); return(xmlXPathNextAncestor(ctxt, cur));}/** * xmlXPathNextFollowingSibling: * @ctxt: the XPath Parser context * @cur: the current node in the traversal * * Traversal function for the "following-sibling" direction * The following-sibling axis contains the following siblings of the context * node in document order. * * Returns the next element following that axis */xmlNodePtrxmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL); if (cur == NULL) return(ctxt->context->node->next); return(cur->next);}/** * xmlXPathNextPrecedingSibling: * @ctxt: the XPath Parser context * @cur: the current node in the traversal * * Traversal function for the "preceding-sibling" direction * The preceding-sibling axis contains the preceding siblings of the context * node in reverse document order; the first preceding sibling is first on the * axis; the sibling preceding that node is the second on the axis and so on. * * Returns the next element following that axis */xmlNodePtrxmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL); if (cur == NULL) return(ctxt->context->node->prev); return(cur->prev);}/** * xmlXPathNextFollowing: * @ctxt: the XPath Parser context * @cur: the current node in the traversal * * Traversal function for the "following" direction * The following axis contains all nodes in the same document as the context * node that are after the context node in document order, excluding any * descendants and excluding attribute nodes and namespace nodes; the nodes * are ordered in document order * * Returns the next element following that axis */xmlNodePtrxmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL); if (cur == NULL) return(ctxt->context->node->next);; /* !!!!!!!!! */ if (cur->children != NULL) return(cur->children); if (cur->next != NULL) return(cur->next); do { cur = cur->parent; if (cur == NULL) return(NULL); if (cur == ctxt->context->doc->children) return(NULL); if (cur->next != NULL) { cur = cur->next; return(cur); } } while (cur != NULL); return(cur);}/** * xmlXPathNextPreceding: * @ctxt: the XPath Parser context * @cur: the current node in the traversal * * Traversal function for the "preceding" direction * the preceding axis contains all nodes in the same document as the context * node that are before the context node in document order, excluding any * ancestors and excluding attribute nodes and namespace nodes; the nodes are * ordered in reverse document order * * Returns the next element following that axis */xmlNodePtrxmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL); if (cur == NULL) return(ctxt->context->node->prev); /* !!!!!!!!! */ if (cur->last != NULL) return(cur->last); if (cur->prev != NULL) return(cur->prev); do { cur = cur->parent; if (cur == NULL) return(NULL); if (cur == ctxt->context->doc->children) return(NULL); if (cur->prev != NULL) { cur = cur->prev; return(cur); } } while (cur != NULL); return(cur);}/** * xmlXPathNextNamespace: * @ctxt: the XPath Parser context * @cur: the current attribute in the traversal * * Traversal function for the "namespace" direction * the namespace axis contains the namespace nodes of the context node; * the order of nodes on this axis is implementation-defined; the axis will * be empty unless the context node is an element * * Returns the next element following that axis */xmlNsPtrxmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlAttrPtr cur) { if ((cur == NULL) || (ctxt->context->namespaces == NULL)) { if (ctxt->context->namespaces != NULL) xmlFree(ctxt->context->namespaces); ctxt->context->namespaces = xmlGetNsList(ctxt->context->doc, ctxt->context->node); if (ctxt->context->namespaces == NULL) return(NULL); ctxt->context->nsNr = 0; } return(ctxt->context->namespaces[ctxt->context->nsNr++]);}/** * xmlXPathNextAttribute: * @ctxt: the XPath Parser context * @cur: the current attribute in the traversal * * Traversal function for the "attribute" direction * TODO: support DTD inherited default attributes * * Returns the next element following that axis */xmlAttrPtrxmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlAttrPtr cur) { if (cur == NULL) { if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc) return(NULL); return(ctxt->context->node->properties); } return(cur->next);}/************************************************************************ * * * NodeTest Functions * * * ************************************************************************/#define NODE_TEST_NONE 0#define NODE_TEST_TYPE 1#define NODE_TEST_PI 2#define NODE_TEST_ALL 3#define NODE_TEST_NS 4#define NODE_TEST_NAME 5#define NODE_TYPE_COMMENT 50#define NODE_TYPE_TEXT 51#define NODE_TYPE_PI 52#define NODE_TYPE_NODE 53#define IS_FUNCTION 200/** * xmlXPathNodeCollectAndTest: * @ctxt: the XPath Parser context * @cur: the current node to test * * This is the function implementing a step: based on the current list * of nodes, it builds up a new list, looking at all nodes under that * axis and selecting them. * * Returns the new NodeSet resulting from the search. */xmlNodeSetPtr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -