mirror of
https://github.com/darlinghq/darling-libxml2.git
synced 2025-03-04 17:18:10 +00:00
Fixes in the plane: - xpath.c: fixed a [] evaluation problem reported -
Fixes in the plane: - xpath.c: fixed a [] evaluation problem reported - test/XPath/tests/simpleaddr: extended test - result/XPath/simpleaddr: updated result Daniel
This commit is contained in:
parent
3197f164a8
commit
d8df6c0e8c
@ -1,3 +1,9 @@
|
|||||||
|
Fri Apr 6 12:53:05 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||||
|
|
||||||
|
* xpath.c: fixed a [] evaluation problem reported
|
||||||
|
* test/XPath/tests/simpleaddr: extended test
|
||||||
|
* result/XPath/simpleaddr: updated result
|
||||||
|
|
||||||
Wed Apr 4 02:07:53 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
Wed Apr 4 02:07:53 CEST 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||||
|
|
||||||
* xmllint.c: Dan Timis reported a portability problem
|
* xmllint.c: Dan Timis reported a portability problem
|
||||||
|
40
aclocal.m4
vendored
40
aclocal.m4
vendored
@ -620,31 +620,35 @@ esac
|
|||||||
])
|
])
|
||||||
|
|
||||||
# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
|
# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
|
||||||
# the libltdl convenience library, adds --enable-ltdl-convenience to
|
# the libltdl convenience library and INCLTDL to the include flags for
|
||||||
# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
|
# the libltdl header and adds --enable-ltdl-convenience to the
|
||||||
# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
|
# configure arguments. Note that LIBLTDL and INCLTDL are not
|
||||||
# to be `${top_builddir}/libltdl'. Make sure you start DIR with
|
# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not
|
||||||
# '${top_builddir}/' (note the single quotes!) if your package is not
|
# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed
|
||||||
# flat, and, if you're not using automake, define top_builddir as
|
# with '${top_builddir}/' and INCLTDL will be prefixed with
|
||||||
# appropriate in the Makefiles.
|
# '${top_srcdir}/' (note the single quotes!). If your package is not
|
||||||
|
# flat and you're not using automake, define top_builddir and
|
||||||
|
# top_srcdir appropriately in the Makefiles.
|
||||||
AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
|
AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
|
||||||
case "$enable_ltdl_convenience" in
|
case "$enable_ltdl_convenience" in
|
||||||
no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
|
no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
|
||||||
"") enable_ltdl_convenience=yes
|
"") enable_ltdl_convenience=yes
|
||||||
ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
|
ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
|
||||||
esac
|
esac
|
||||||
LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
|
LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
|
||||||
INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
|
INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
|
||||||
])
|
])
|
||||||
|
|
||||||
# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
|
# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
|
||||||
# the libltdl installable library, and adds --enable-ltdl-install to
|
# the libltdl installable library and INCLTDL to the include flags for
|
||||||
# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
|
# the libltdl header and adds --enable-ltdl-install to the configure
|
||||||
# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
|
# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
|
||||||
# to be `${top_builddir}/libltdl'. Make sure you start DIR with
|
# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed
|
||||||
# '${top_builddir}/' (note the single quotes!) if your package is not
|
# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will
|
||||||
# flat, and, if you're not using automake, define top_builddir as
|
# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
|
||||||
# appropriate in the Makefiles.
|
# with '${top_srcdir}/' (note the single quotes!). If your package is
|
||||||
|
# not flat and you're not using automake, define top_builddir and
|
||||||
|
# top_srcdir appropriately in the Makefiles.
|
||||||
# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
|
# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
|
||||||
AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
|
AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
|
||||||
AC_CHECK_LIB(ltdl, main,
|
AC_CHECK_LIB(ltdl, main,
|
||||||
@ -657,8 +661,8 @@ AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
|
|||||||
])
|
])
|
||||||
if test x"$enable_ltdl_install" = x"yes"; then
|
if test x"$enable_ltdl_install" = x"yes"; then
|
||||||
ac_configure_args="$ac_configure_args --enable-ltdl-install"
|
ac_configure_args="$ac_configure_args --enable-ltdl-install"
|
||||||
LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
|
LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
|
||||||
INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
|
INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
|
||||||
else
|
else
|
||||||
ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
|
ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
|
||||||
LIBLTDL="-lltdl"
|
LIBLTDL="-lltdl"
|
||||||
|
@ -51,12 +51,30 @@ Set contains 2 nodes:
|
|||||||
========================
|
========================
|
||||||
Expression: //p/text()[position()=1]
|
Expression: //p/text()[position()=1]
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
|
Set contains 2 nodes:
|
||||||
|
1 TEXT
|
||||||
|
content=bla bla bla ...
|
||||||
|
2 TEXT
|
||||||
|
content=...
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: //p/text()[position()=last()]
|
||||||
|
Object is a Node Set :
|
||||||
|
Set contains 2 nodes:
|
||||||
|
1 TEXT
|
||||||
|
content=bla bla bla ...
|
||||||
|
2 TEXT
|
||||||
|
content=...
|
||||||
|
|
||||||
|
========================
|
||||||
|
Expression: (//p/text())[position()=1]
|
||||||
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 TEXT
|
1 TEXT
|
||||||
content=bla bla bla ...
|
content=bla bla bla ...
|
||||||
|
|
||||||
========================
|
========================
|
||||||
Expression: //p/text()[position()=last()]
|
Expression: (//p/text())[position()=last()]
|
||||||
Object is a Node Set :
|
Object is a Node Set :
|
||||||
Set contains 1 nodes:
|
Set contains 1 nodes:
|
||||||
1 TEXT
|
1 TEXT
|
||||||
|
@ -6,3 +6,5 @@
|
|||||||
//p/text()
|
//p/text()
|
||||||
//p/text()[position()=1]
|
//p/text()[position()=1]
|
||||||
//p/text()[position()=last()]
|
//p/text()[position()=last()]
|
||||||
|
(//p/text())[position()=1]
|
||||||
|
(//p/text())[position()=last()]
|
||||||
|
@ -113,6 +113,7 @@ testXPath(const char *str) {
|
|||||||
xmlXPathDebugDumpCompExpr(stdout, comp, 0);
|
xmlXPathDebugDumpCompExpr(stdout, comp, 0);
|
||||||
|
|
||||||
res = xmlXPathCompiledEval(comp, ctxt);
|
res = xmlXPathCompiledEval(comp, ctxt);
|
||||||
|
xmlXPathFreeCompExpr(comp);
|
||||||
} else
|
} else
|
||||||
res = NULL;
|
res = NULL;
|
||||||
}
|
}
|
||||||
|
770
xpath.c
770
xpath.c
@ -204,6 +204,7 @@ typedef enum {
|
|||||||
XPATH_OP_FUNCTION,
|
XPATH_OP_FUNCTION,
|
||||||
XPATH_OP_ARG,
|
XPATH_OP_ARG,
|
||||||
XPATH_OP_PREDICATE,
|
XPATH_OP_PREDICATE,
|
||||||
|
XPATH_OP_FILTER,
|
||||||
XPATH_OP_SORT
|
XPATH_OP_SORT
|
||||||
#ifdef LIBXML_XPTR_ENABLED
|
#ifdef LIBXML_XPTR_ENABLED
|
||||||
,XPATH_OP_RANGETO
|
,XPATH_OP_RANGETO
|
||||||
@ -378,6 +379,9 @@ xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2,
|
|||||||
return(comp->nbStep++);
|
return(comp->nbStep++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5) \
|
||||||
|
xmlXPathCompExprAdd(ctxt->comp, (op1), (op2), \
|
||||||
|
(op), (val), (val2), (val3), (val4), (val5))
|
||||||
#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5) \
|
#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5) \
|
||||||
xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1, \
|
xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1, \
|
||||||
(op), (val), (val2), (val3), (val4), (val5))
|
(op), (val), (val2), (val3), (val4), (val5))
|
||||||
@ -782,6 +786,7 @@ xmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp,
|
|||||||
}
|
}
|
||||||
case XPATH_OP_ARG: fprintf(output, "ARG"); break;
|
case XPATH_OP_ARG: fprintf(output, "ARG"); break;
|
||||||
case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break;
|
case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break;
|
||||||
|
case XPATH_OP_FILTER: fprintf(output, "FILTER"); break;
|
||||||
default:
|
default:
|
||||||
fprintf(output, "UNKNOWN %d\n", op->op); return;
|
fprintf(output, "UNKNOWN %d\n", op->op); return;
|
||||||
}
|
}
|
||||||
@ -1096,6 +1101,9 @@ xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file,
|
|||||||
|
|
||||||
cur = ctxt->cur;
|
cur = ctxt->cur;
|
||||||
base = ctxt->base;
|
base = ctxt->base;
|
||||||
|
if ((cur == NULL) || (base == NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
|
while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
|
||||||
cur--;
|
cur--;
|
||||||
}
|
}
|
||||||
@ -1376,7 +1384,7 @@ xmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
|
|||||||
*/
|
*/
|
||||||
xmlNodeSetPtr
|
xmlNodeSetPtr
|
||||||
xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
|
xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
|
||||||
int i, j, initNr;
|
int i, j, initNr, skip;
|
||||||
|
|
||||||
if (val2 == NULL) return(val1);
|
if (val2 == NULL) return(val1);
|
||||||
if (val1 == NULL) {
|
if (val1 == NULL) {
|
||||||
@ -1389,8 +1397,15 @@ xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
|
|||||||
/*
|
/*
|
||||||
* check against doublons
|
* check against doublons
|
||||||
*/
|
*/
|
||||||
for (j = 0; j < initNr; j++)
|
skip = 0;
|
||||||
if (val1->nodeTab[j] == val2->nodeTab[i]) continue;
|
for (j = 0; j < initNr; j++) {
|
||||||
|
if (val1->nodeTab[j] == val2->nodeTab[i]) {
|
||||||
|
skip = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (skip)
|
||||||
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* grow the nodeTab if needed
|
* grow the nodeTab if needed
|
||||||
@ -2555,12 +2570,12 @@ xmlXPathCompareNodeSets(int inf, int strict,
|
|||||||
ns1 = arg1->nodesetval;
|
ns1 = arg1->nodesetval;
|
||||||
ns2 = arg2->nodesetval;
|
ns2 = arg2->nodesetval;
|
||||||
|
|
||||||
if (ns1->nodeNr <= 0) {
|
if ((ns1 == NULL) || (ns1->nodeNr <= 0)) {
|
||||||
xmlXPathFreeObject(arg1);
|
xmlXPathFreeObject(arg1);
|
||||||
xmlXPathFreeObject(arg2);
|
xmlXPathFreeObject(arg2);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
if (ns2->nodeNr <= 0) {
|
if ((ns2 == NULL) || (ns2->nodeNr <= 0)) {
|
||||||
xmlXPathFreeObject(arg1);
|
xmlXPathFreeObject(arg1);
|
||||||
xmlXPathFreeObject(arg2);
|
xmlXPathFreeObject(arg2);
|
||||||
return(0);
|
return(0);
|
||||||
@ -2685,6 +2700,8 @@ xmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const xmlChar *str) {
|
|||||||
((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
|
((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
|
||||||
return(0);
|
return(0);
|
||||||
ns = arg->nodesetval;
|
ns = arg->nodesetval;
|
||||||
|
if (ns == NULL)
|
||||||
|
return(0);
|
||||||
if (ns->nodeNr <= 0)
|
if (ns->nodeNr <= 0)
|
||||||
return(0);
|
return(0);
|
||||||
for (i = 0;i < ns->nodeNr;i++) {
|
for (i = 0;i < ns->nodeNr;i++) {
|
||||||
@ -3752,339 +3769,6 @@ xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
|
|
||||||
#define IS_FUNCTION 200
|
#define IS_FUNCTION 200
|
||||||
|
|
||||||
/**
|
|
||||||
* xmlXPathNodeCollectAndTest:
|
|
||||||
* @ctxt: the XPath Parser context
|
|
||||||
* @axis: the XPath axis
|
|
||||||
* @test: the XPath test
|
|
||||||
* @type: the XPath type
|
|
||||||
* @prefix: the namesapce prefix if any
|
|
||||||
* @name: the name used in the search if any
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|
||||||
xmlXPathTestVal test, xmlXPathTypeVal type,
|
|
||||||
const xmlChar *prefix, const xmlChar *name) {
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
int n = 0, t = 0;
|
|
||||||
#endif
|
|
||||||
int i;
|
|
||||||
xmlNodeSetPtr ret;
|
|
||||||
xmlXPathTraversalFunction next = NULL;
|
|
||||||
void (*addNode)(xmlNodeSetPtr, xmlNodePtr);
|
|
||||||
xmlNodePtr cur = NULL;
|
|
||||||
xmlXPathObjectPtr obj;
|
|
||||||
xmlNodeSetPtr nodelist;
|
|
||||||
xmlNodePtr tmp;
|
|
||||||
|
|
||||||
CHECK_TYPE(XPATH_NODESET);
|
|
||||||
obj = valuePop(ctxt);
|
|
||||||
addNode = xmlXPathNodeSetAdd;
|
|
||||||
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"new step : ");
|
|
||||||
#endif
|
|
||||||
switch (axis) {
|
|
||||||
case AXIS_ANCESTOR:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'ancestors' ");
|
|
||||||
#endif
|
|
||||||
next = xmlXPathNextAncestor; break;
|
|
||||||
case AXIS_ANCESTOR_OR_SELF:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'ancestors-or-self' ");
|
|
||||||
#endif
|
|
||||||
next = xmlXPathNextAncestorOrSelf; break;
|
|
||||||
case AXIS_ATTRIBUTE:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'attributes' ");
|
|
||||||
#endif
|
|
||||||
next = xmlXPathNextAttribute; break;
|
|
||||||
break;
|
|
||||||
case AXIS_CHILD:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'child' ");
|
|
||||||
#endif
|
|
||||||
next = xmlXPathNextChild; break;
|
|
||||||
case AXIS_DESCENDANT:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'descendant' ");
|
|
||||||
#endif
|
|
||||||
next = xmlXPathNextDescendant; break;
|
|
||||||
case AXIS_DESCENDANT_OR_SELF:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'descendant-or-self' ");
|
|
||||||
#endif
|
|
||||||
next = xmlXPathNextDescendantOrSelf; break;
|
|
||||||
case AXIS_FOLLOWING:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'following' ");
|
|
||||||
#endif
|
|
||||||
next = xmlXPathNextFollowing; break;
|
|
||||||
case AXIS_FOLLOWING_SIBLING:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'following-siblings' ");
|
|
||||||
#endif
|
|
||||||
next = xmlXPathNextFollowingSibling; break;
|
|
||||||
case AXIS_NAMESPACE:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'namespace' ");
|
|
||||||
#endif
|
|
||||||
next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; break;
|
|
||||||
break;
|
|
||||||
case AXIS_PARENT:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'parent' ");
|
|
||||||
#endif
|
|
||||||
next = xmlXPathNextParent; break;
|
|
||||||
case AXIS_PRECEDING:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'preceding' ");
|
|
||||||
#endif
|
|
||||||
next = xmlXPathNextPreceding; break;
|
|
||||||
case AXIS_PRECEDING_SIBLING:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'preceding-sibling' ");
|
|
||||||
#endif
|
|
||||||
next = xmlXPathNextPrecedingSibling; break;
|
|
||||||
case AXIS_SELF:
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"axis 'self' ");
|
|
||||||
#endif
|
|
||||||
next = xmlXPathNextSelf; break;
|
|
||||||
}
|
|
||||||
if (next == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
nodelist = obj->nodesetval;
|
|
||||||
if ((nodelist != NULL) &&
|
|
||||||
(nodelist->nodeNr <= 1))
|
|
||||||
addNode = xmlXPathNodeSetAddUnique;
|
|
||||||
else
|
|
||||||
addNode = xmlXPathNodeSetAdd;
|
|
||||||
ret = xmlXPathNodeSetCreate(NULL);
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
" context contains %d nodes\n",
|
|
||||||
nodelist->nodeNr);
|
|
||||||
switch (test) {
|
|
||||||
case NODE_TEST_NODE:
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
" searching all nodes\n");
|
|
||||||
break;
|
|
||||||
case NODE_TEST_NONE:
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
" searching for none !!!\n");
|
|
||||||
break;
|
|
||||||
case NODE_TEST_TYPE:
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
" searching for type %d\n", type);
|
|
||||||
break;
|
|
||||||
case NODE_TEST_PI:
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
" searching for PI !!!\n");
|
|
||||||
break;
|
|
||||||
case NODE_TEST_ALL:
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
" searching for *\n");
|
|
||||||
break;
|
|
||||||
case NODE_TEST_NS:
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
" searching for namespace %s\n",
|
|
||||||
prefix);
|
|
||||||
break;
|
|
||||||
case NODE_TEST_NAME:
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
" searching for name %s\n", name);
|
|
||||||
if (prefix != NULL)
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
" with namespace %s\n",
|
|
||||||
prefix);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
xmlGenericError(xmlGenericErrorContext, "Testing : ");
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* 2.3 Node Tests
|
|
||||||
* - For the attribute axis, the principal node type is attribute.
|
|
||||||
* - For the namespace axis, the principal node type is namespace.
|
|
||||||
* - For other axes, the principal node type is element.
|
|
||||||
*
|
|
||||||
* A node test * is true for any node of the
|
|
||||||
* principal node type. For example, child::* willi
|
|
||||||
* select all element children of the context node
|
|
||||||
*/
|
|
||||||
tmp = ctxt->context->node;
|
|
||||||
for (i = 0;i < nodelist->nodeNr; i++) {
|
|
||||||
ctxt->context->node = nodelist->nodeTab[i];
|
|
||||||
|
|
||||||
cur = NULL;
|
|
||||||
do {
|
|
||||||
cur = next(ctxt, cur);
|
|
||||||
if (cur == NULL) break;
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
t++;
|
|
||||||
xmlGenericError(xmlGenericErrorContext, " %s", cur->name);
|
|
||||||
#endif
|
|
||||||
switch (test) {
|
|
||||||
case NODE_TEST_NONE:
|
|
||||||
ctxt->context->node = tmp;
|
|
||||||
STRANGE
|
|
||||||
return;
|
|
||||||
case NODE_TEST_TYPE:
|
|
||||||
if ((cur->type == type) ||
|
|
||||||
((type == NODE_TYPE_NODE) &&
|
|
||||||
((cur->type == XML_DOCUMENT_NODE) ||
|
|
||||||
(cur->type == XML_HTML_DOCUMENT_NODE) ||
|
|
||||||
(cur->type == XML_ELEMENT_NODE) ||
|
|
||||||
(cur->type == XML_PI_NODE) ||
|
|
||||||
(cur->type == XML_COMMENT_NODE) ||
|
|
||||||
(cur->type == XML_CDATA_SECTION_NODE) ||
|
|
||||||
(cur->type == XML_TEXT_NODE)))) {
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
n++;
|
|
||||||
#endif
|
|
||||||
addNode(ret, cur);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NODE_TEST_PI:
|
|
||||||
if (cur->type == XML_PI_NODE) {
|
|
||||||
if ((name != NULL) &&
|
|
||||||
(!xmlStrEqual(name, cur->name)))
|
|
||||||
break;
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
n++;
|
|
||||||
#endif
|
|
||||||
addNode(ret, cur);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NODE_TEST_ALL:
|
|
||||||
if (axis == AXIS_ATTRIBUTE) {
|
|
||||||
if (cur->type == XML_ATTRIBUTE_NODE) {
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
n++;
|
|
||||||
#endif
|
|
||||||
addNode(ret, cur);
|
|
||||||
}
|
|
||||||
} else if (axis == AXIS_NAMESPACE) {
|
|
||||||
if (cur->type == XML_NAMESPACE_DECL) {
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
n++;
|
|
||||||
#endif
|
|
||||||
addNode(ret, cur);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((cur->type == XML_ELEMENT_NODE) ||
|
|
||||||
(cur->type == XML_DOCUMENT_NODE) ||
|
|
||||||
(cur->type == XML_HTML_DOCUMENT_NODE)) {
|
|
||||||
if (prefix == NULL) {
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
n++;
|
|
||||||
#endif
|
|
||||||
addNode(ret, cur);
|
|
||||||
} else if ((cur->ns != NULL) &&
|
|
||||||
(xmlStrEqual(prefix,
|
|
||||||
cur->ns->href))) {
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
n++;
|
|
||||||
#endif
|
|
||||||
addNode(ret, cur);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NODE_TEST_NS: {
|
|
||||||
TODO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case NODE_TEST_NAME:
|
|
||||||
switch (cur->type) {
|
|
||||||
case XML_ELEMENT_NODE:
|
|
||||||
if (xmlStrEqual(name, cur->name)) {
|
|
||||||
if (prefix == NULL) {
|
|
||||||
if ((cur->ns == NULL) ||
|
|
||||||
(cur->ns->prefix == NULL)) {
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
n++;
|
|
||||||
#endif
|
|
||||||
addNode(ret, cur);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((cur->ns != NULL) &&
|
|
||||||
(xmlStrEqual(prefix,
|
|
||||||
cur->ns->href))) {
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
n++;
|
|
||||||
#endif
|
|
||||||
addNode(ret, cur);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case XML_ATTRIBUTE_NODE: {
|
|
||||||
xmlAttrPtr attr = (xmlAttrPtr) cur;
|
|
||||||
if (xmlStrEqual(name, attr->name)) {
|
|
||||||
if (prefix == NULL) {
|
|
||||||
if ((attr->ns == NULL) ||
|
|
||||||
(attr->ns->prefix == NULL)) {
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
n++;
|
|
||||||
#endif
|
|
||||||
addNode(ret, (xmlNodePtr) attr);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((attr->ns != NULL) &&
|
|
||||||
(xmlStrEqual(prefix,
|
|
||||||
attr->ns->href))) {
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
n++;
|
|
||||||
#endif
|
|
||||||
addNode(ret, (xmlNodePtr) attr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case XML_NAMESPACE_DECL: {
|
|
||||||
TODO;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (cur != NULL);
|
|
||||||
}
|
|
||||||
ctxt->context->node = tmp;
|
|
||||||
#ifdef DEBUG_STEP
|
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
|
||||||
"\nExamined %d nodes, found %d nodes at that step\n", t, n);
|
|
||||||
#endif
|
|
||||||
xmlXPathFreeObject(obj);
|
|
||||||
valuePush(ctxt, xmlXPathWrapNodeSet(ret));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
@ -5280,7 +4964,7 @@ xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
XP_ERROR(XPATH_INVALID_TYPE);
|
XP_ERROR(XPATH_INVALID_TYPE);
|
||||||
cur = valuePop(ctxt);
|
cur = valuePop(ctxt);
|
||||||
|
|
||||||
if (cur->nodesetval->nodeNr == 0) {
|
if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
|
||||||
valuePush(ctxt, xmlXPathNewFloat(0.0));
|
valuePush(ctxt, xmlXPathNewFloat(0.0));
|
||||||
} else {
|
} else {
|
||||||
valuePush(ctxt,
|
valuePush(ctxt,
|
||||||
@ -5392,7 +5076,7 @@ xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
* implementation.
|
* implementation.
|
||||||
*/
|
*/
|
||||||
static void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt);
|
static void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt);
|
||||||
static void xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt);
|
static void xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter);
|
||||||
static void xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt);
|
static void xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt);
|
||||||
#ifdef VMS
|
#ifdef VMS
|
||||||
static void xmlXPathCompRelLocationPath(xmlXPathParserContextPtr ctxt);
|
static void xmlXPathCompRelLocationPath(xmlXPathParserContextPtr ctxt);
|
||||||
@ -5865,7 +5549,7 @@ xmlXPathCompFilterExpr(xmlXPathParserContextPtr ctxt) {
|
|||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
|
|
||||||
while (CUR == '[') {
|
while (CUR == '[') {
|
||||||
xmlXPathCompPredicate(ctxt);
|
xmlXPathCompPredicate(ctxt, 1);
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6358,6 +6042,7 @@ xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt) {
|
|||||||
/**
|
/**
|
||||||
* xmlXPathCompPredicate:
|
* xmlXPathCompPredicate:
|
||||||
* @ctxt: the XPath Parser context
|
* @ctxt: the XPath Parser context
|
||||||
|
* @filter: act as a filter
|
||||||
*
|
*
|
||||||
* [8] Predicate ::= '[' PredicateExpr ']'
|
* [8] Predicate ::= '[' PredicateExpr ']'
|
||||||
* [9] PredicateExpr ::= Expr
|
* [9] PredicateExpr ::= Expr
|
||||||
@ -6365,7 +6050,7 @@ xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt) {
|
|||||||
* Compile a predicate expression
|
* Compile a predicate expression
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt) {
|
xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) {
|
||||||
int op1 = ctxt->comp->last;
|
int op1 = ctxt->comp->last;
|
||||||
|
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
@ -6383,7 +6068,10 @@ xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt) {
|
|||||||
XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
|
XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
PUSH_BINARY_EXPR(XPATH_OP_PREDICATE, op1, ctxt->comp->last, 0, 0);
|
if (filter)
|
||||||
|
PUSH_BINARY_EXPR(XPATH_OP_FILTER, op1, ctxt->comp->last, 0, 0);
|
||||||
|
else
|
||||||
|
PUSH_BINARY_EXPR(XPATH_OP_PREDICATE, op1, ctxt->comp->last, 0, 0);
|
||||||
|
|
||||||
NEXT;
|
NEXT;
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
@ -6637,8 +6325,9 @@ xmlXPathCompStep(xmlXPathParserContextPtr ctxt) {
|
|||||||
xmlChar *name = NULL;
|
xmlChar *name = NULL;
|
||||||
const xmlChar *prefix = NULL;
|
const xmlChar *prefix = NULL;
|
||||||
xmlXPathTestVal test;
|
xmlXPathTestVal test;
|
||||||
xmlXPathAxisVal axis;
|
xmlXPathAxisVal axis = 0;
|
||||||
xmlXPathTypeVal type;
|
xmlXPathTypeVal type;
|
||||||
|
int op1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The modification needed for XPointer change to the production
|
* The modification needed for XPointer change to the production
|
||||||
@ -6647,7 +6336,7 @@ xmlXPathCompStep(xmlXPathParserContextPtr ctxt) {
|
|||||||
if (ctxt->xptr) {
|
if (ctxt->xptr) {
|
||||||
name = xmlXPathParseNCName(ctxt);
|
name = xmlXPathParseNCName(ctxt);
|
||||||
if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) {
|
if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) {
|
||||||
int op1 = ctxt->comp->last;
|
int op2 = ctxt->comp->last;
|
||||||
xmlFree(name);
|
xmlFree(name);
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if (CUR != '(') {
|
if (CUR != '(') {
|
||||||
@ -6657,7 +6346,7 @@ xmlXPathCompStep(xmlXPathParserContextPtr ctxt) {
|
|||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
|
|
||||||
xmlXPathCompileExpr(ctxt);
|
xmlXPathCompileExpr(ctxt);
|
||||||
PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op1, ctxt->comp->last, 0, 0);
|
PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, ctxt->comp->last, 0, 0);
|
||||||
CHECK_ERROR;
|
CHECK_ERROR;
|
||||||
|
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
@ -6704,19 +6393,23 @@ xmlXPathCompStep(xmlXPathParserContextPtr ctxt) {
|
|||||||
"Basis : computing new set\n");
|
"Basis : computing new set\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PUSH_LONG_EXPR(XPATH_OP_COLLECT, axis, test, type,
|
|
||||||
(void *)prefix, (void *)name);
|
|
||||||
|
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
xmlGenericError(xmlGenericErrorContext, "Basis : ");
|
xmlGenericError(xmlGenericErrorContext, "Basis : ");
|
||||||
xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval);
|
xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
eval_predicates:
|
eval_predicates:
|
||||||
|
op1 = ctxt->comp->last;
|
||||||
|
ctxt->comp->last = -1;
|
||||||
|
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
while (CUR == '[') {
|
while (CUR == '[') {
|
||||||
xmlXPathCompPredicate(ctxt);
|
xmlXPathCompPredicate(ctxt, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis,
|
||||||
|
test, type, (void *)prefix, (void *)name);
|
||||||
|
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
xmlGenericError(xmlGenericErrorContext, "Step : ");
|
xmlGenericError(xmlGenericErrorContext, "Step : ");
|
||||||
@ -6821,6 +6514,366 @@ xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) {
|
|||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathNodeCollectAndTest:
|
||||||
|
* @ctxt: the XPath Parser context
|
||||||
|
* @op: the XPath precompiled step operation
|
||||||
|
*
|
||||||
|
* 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 it also do the predicate filtering
|
||||||
|
*
|
||||||
|
* Pushes the new NodeSet resulting from the search.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
|
||||||
|
xmlXPathStepOpPtr op) {
|
||||||
|
xmlXPathAxisVal axis = op->value;
|
||||||
|
xmlXPathTestVal test = op->value2;
|
||||||
|
xmlXPathTypeVal type = op->value3;
|
||||||
|
const xmlChar *prefix = op->value4;
|
||||||
|
const xmlChar *name = op->value5;
|
||||||
|
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
int n = 0, t = 0;
|
||||||
|
#endif
|
||||||
|
int i;
|
||||||
|
xmlNodeSetPtr ret, list;
|
||||||
|
xmlXPathTraversalFunction next = NULL;
|
||||||
|
void (*addNode)(xmlNodeSetPtr, xmlNodePtr);
|
||||||
|
xmlNodePtr cur = NULL;
|
||||||
|
xmlXPathObjectPtr obj;
|
||||||
|
xmlNodeSetPtr nodelist;
|
||||||
|
xmlNodePtr tmp;
|
||||||
|
|
||||||
|
CHECK_TYPE(XPATH_NODESET);
|
||||||
|
obj = valuePop(ctxt);
|
||||||
|
addNode = xmlXPathNodeSetAdd;
|
||||||
|
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"new step : ");
|
||||||
|
#endif
|
||||||
|
switch (axis) {
|
||||||
|
case AXIS_ANCESTOR:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'ancestors' ");
|
||||||
|
#endif
|
||||||
|
next = xmlXPathNextAncestor; break;
|
||||||
|
case AXIS_ANCESTOR_OR_SELF:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'ancestors-or-self' ");
|
||||||
|
#endif
|
||||||
|
next = xmlXPathNextAncestorOrSelf; break;
|
||||||
|
case AXIS_ATTRIBUTE:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'attributes' ");
|
||||||
|
#endif
|
||||||
|
next = xmlXPathNextAttribute; break;
|
||||||
|
break;
|
||||||
|
case AXIS_CHILD:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'child' ");
|
||||||
|
#endif
|
||||||
|
next = xmlXPathNextChild; break;
|
||||||
|
case AXIS_DESCENDANT:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'descendant' ");
|
||||||
|
#endif
|
||||||
|
next = xmlXPathNextDescendant; break;
|
||||||
|
case AXIS_DESCENDANT_OR_SELF:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'descendant-or-self' ");
|
||||||
|
#endif
|
||||||
|
next = xmlXPathNextDescendantOrSelf; break;
|
||||||
|
case AXIS_FOLLOWING:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'following' ");
|
||||||
|
#endif
|
||||||
|
next = xmlXPathNextFollowing; break;
|
||||||
|
case AXIS_FOLLOWING_SIBLING:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'following-siblings' ");
|
||||||
|
#endif
|
||||||
|
next = xmlXPathNextFollowingSibling; break;
|
||||||
|
case AXIS_NAMESPACE:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'namespace' ");
|
||||||
|
#endif
|
||||||
|
next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; break;
|
||||||
|
break;
|
||||||
|
case AXIS_PARENT:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'parent' ");
|
||||||
|
#endif
|
||||||
|
next = xmlXPathNextParent; break;
|
||||||
|
case AXIS_PRECEDING:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'preceding' ");
|
||||||
|
#endif
|
||||||
|
next = xmlXPathNextPreceding; break;
|
||||||
|
case AXIS_PRECEDING_SIBLING:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'preceding-sibling' ");
|
||||||
|
#endif
|
||||||
|
next = xmlXPathNextPrecedingSibling; break;
|
||||||
|
case AXIS_SELF:
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"axis 'self' ");
|
||||||
|
#endif
|
||||||
|
next = xmlXPathNextSelf; break;
|
||||||
|
}
|
||||||
|
if (next == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nodelist = obj->nodesetval;
|
||||||
|
if (nodelist == NULL) {
|
||||||
|
xmlXPathFreeObject(obj);
|
||||||
|
valuePush(ctxt, xmlXPathWrapNodeSet(NULL));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
addNode = xmlXPathNodeSetAddUnique;
|
||||||
|
ret = NULL;
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
" context contains %d nodes\n",
|
||||||
|
nodelist->nodeNr);
|
||||||
|
switch (test) {
|
||||||
|
case NODE_TEST_NODE:
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
" searching all nodes\n");
|
||||||
|
break;
|
||||||
|
case NODE_TEST_NONE:
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
" searching for none !!!\n");
|
||||||
|
break;
|
||||||
|
case NODE_TEST_TYPE:
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
" searching for type %d\n", type);
|
||||||
|
break;
|
||||||
|
case NODE_TEST_PI:
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
" searching for PI !!!\n");
|
||||||
|
break;
|
||||||
|
case NODE_TEST_ALL:
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
" searching for *\n");
|
||||||
|
break;
|
||||||
|
case NODE_TEST_NS:
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
" searching for namespace %s\n",
|
||||||
|
prefix);
|
||||||
|
break;
|
||||||
|
case NODE_TEST_NAME:
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
" searching for name %s\n", name);
|
||||||
|
if (prefix != NULL)
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
" with namespace %s\n",
|
||||||
|
prefix);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
xmlGenericError(xmlGenericErrorContext, "Testing : ");
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* 2.3 Node Tests
|
||||||
|
* - For the attribute axis, the principal node type is attribute.
|
||||||
|
* - For the namespace axis, the principal node type is namespace.
|
||||||
|
* - For other axes, the principal node type is element.
|
||||||
|
*
|
||||||
|
* A node test * is true for any node of the
|
||||||
|
* principal node type. For example, child::* willi
|
||||||
|
* select all element children of the context node
|
||||||
|
*/
|
||||||
|
tmp = ctxt->context->node;
|
||||||
|
for (i = 0;i < nodelist->nodeNr; i++) {
|
||||||
|
ctxt->context->node = nodelist->nodeTab[i];
|
||||||
|
|
||||||
|
cur = NULL;
|
||||||
|
list = xmlXPathNodeSetCreate(NULL);
|
||||||
|
do {
|
||||||
|
cur = next(ctxt, cur);
|
||||||
|
if (cur == NULL) break;
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
t++;
|
||||||
|
xmlGenericError(xmlGenericErrorContext, " %s", cur->name);
|
||||||
|
#endif
|
||||||
|
switch (test) {
|
||||||
|
case NODE_TEST_NONE:
|
||||||
|
ctxt->context->node = tmp;
|
||||||
|
STRANGE
|
||||||
|
return;
|
||||||
|
case NODE_TEST_TYPE:
|
||||||
|
if ((cur->type == type) ||
|
||||||
|
((type == NODE_TYPE_NODE) &&
|
||||||
|
((cur->type == XML_DOCUMENT_NODE) ||
|
||||||
|
(cur->type == XML_HTML_DOCUMENT_NODE) ||
|
||||||
|
(cur->type == XML_ELEMENT_NODE) ||
|
||||||
|
(cur->type == XML_PI_NODE) ||
|
||||||
|
(cur->type == XML_COMMENT_NODE) ||
|
||||||
|
(cur->type == XML_CDATA_SECTION_NODE) ||
|
||||||
|
(cur->type == XML_TEXT_NODE)))) {
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
n++;
|
||||||
|
#endif
|
||||||
|
addNode(list, cur);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NODE_TEST_PI:
|
||||||
|
if (cur->type == XML_PI_NODE) {
|
||||||
|
if ((name != NULL) &&
|
||||||
|
(!xmlStrEqual(name, cur->name)))
|
||||||
|
break;
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
n++;
|
||||||
|
#endif
|
||||||
|
addNode(list, cur);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NODE_TEST_ALL:
|
||||||
|
if (axis == AXIS_ATTRIBUTE) {
|
||||||
|
if (cur->type == XML_ATTRIBUTE_NODE) {
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
n++;
|
||||||
|
#endif
|
||||||
|
addNode(list, cur);
|
||||||
|
}
|
||||||
|
} else if (axis == AXIS_NAMESPACE) {
|
||||||
|
if (cur->type == XML_NAMESPACE_DECL) {
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
n++;
|
||||||
|
#endif
|
||||||
|
addNode(list, cur);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((cur->type == XML_ELEMENT_NODE) ||
|
||||||
|
(cur->type == XML_DOCUMENT_NODE) ||
|
||||||
|
(cur->type == XML_HTML_DOCUMENT_NODE)) {
|
||||||
|
if (prefix == NULL) {
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
n++;
|
||||||
|
#endif
|
||||||
|
addNode(list, cur);
|
||||||
|
} else if ((cur->ns != NULL) &&
|
||||||
|
(xmlStrEqual(prefix,
|
||||||
|
cur->ns->href))) {
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
n++;
|
||||||
|
#endif
|
||||||
|
addNode(list, cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NODE_TEST_NS: {
|
||||||
|
TODO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case NODE_TEST_NAME:
|
||||||
|
switch (cur->type) {
|
||||||
|
case XML_ELEMENT_NODE:
|
||||||
|
if (xmlStrEqual(name, cur->name)) {
|
||||||
|
if (prefix == NULL) {
|
||||||
|
if ((cur->ns == NULL) ||
|
||||||
|
(cur->ns->prefix == NULL)) {
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
n++;
|
||||||
|
#endif
|
||||||
|
addNode(list, cur);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((cur->ns != NULL) &&
|
||||||
|
(xmlStrEqual(prefix,
|
||||||
|
cur->ns->href))) {
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
n++;
|
||||||
|
#endif
|
||||||
|
addNode(list, cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XML_ATTRIBUTE_NODE: {
|
||||||
|
xmlAttrPtr attr = (xmlAttrPtr) cur;
|
||||||
|
if (xmlStrEqual(name, attr->name)) {
|
||||||
|
if (prefix == NULL) {
|
||||||
|
if ((attr->ns == NULL) ||
|
||||||
|
(attr->ns->prefix == NULL)) {
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
n++;
|
||||||
|
#endif
|
||||||
|
addNode(list, (xmlNodePtr) attr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((attr->ns != NULL) &&
|
||||||
|
(xmlStrEqual(prefix,
|
||||||
|
attr->ns->href))) {
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
n++;
|
||||||
|
#endif
|
||||||
|
addNode(list, (xmlNodePtr) attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XML_NAMESPACE_DECL: {
|
||||||
|
TODO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (cur != NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there is some predicate filtering do it now
|
||||||
|
*/
|
||||||
|
if (op->ch2 != -1) {
|
||||||
|
xmlXPathObjectPtr obj2;
|
||||||
|
|
||||||
|
valuePush(ctxt, xmlXPathWrapNodeSet(list));
|
||||||
|
xmlXPathCompOpEval(ctxt, &ctxt->comp->steps[op->ch2]);
|
||||||
|
CHECK_TYPE(XPATH_NODESET);
|
||||||
|
obj2 = valuePop(ctxt);
|
||||||
|
list = obj2->nodesetval;
|
||||||
|
obj2->nodesetval = NULL;
|
||||||
|
xmlXPathFreeObject(obj2);
|
||||||
|
}
|
||||||
|
if (ret == NULL) {
|
||||||
|
ret = list;
|
||||||
|
} else {
|
||||||
|
ret = xmlXPathNodeSetMerge(ret, list);
|
||||||
|
xmlXPathFreeNodeSet(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctxt->context->node = tmp;
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"\nExamined %d nodes, found %d nodes at that step\n", t, n);
|
||||||
|
#endif
|
||||||
|
xmlXPathFreeObject(obj);
|
||||||
|
valuePush(ctxt, xmlXPathWrapNodeSet(ret));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXPathCompOpEval:
|
* xmlXPathCompOpEval:
|
||||||
* @ctxt: the XPath parser context with the compiled expression
|
* @ctxt: the XPath parser context with the compiled expression
|
||||||
@ -6929,12 +6982,14 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) {
|
|||||||
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||||
ctxt->context->node = NULL;
|
ctxt->context->node = NULL;
|
||||||
return;
|
return;
|
||||||
case XPATH_OP_COLLECT:
|
case XPATH_OP_COLLECT: {
|
||||||
if (op->ch1 != -1)
|
if (op->ch1 == -1)
|
||||||
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
return;
|
||||||
xmlXPathNodeCollectAndTest(ctxt, op->value, op->value2,
|
|
||||||
op->value3, op->value4, op->value5);
|
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
|
||||||
|
xmlXPathNodeCollectAndTest(ctxt, op);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
case XPATH_OP_VALUE:
|
case XPATH_OP_VALUE:
|
||||||
valuePush(ctxt,
|
valuePush(ctxt,
|
||||||
xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4));
|
xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4));
|
||||||
@ -6995,7 +7050,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) {
|
|||||||
if (op->ch2 != -1)
|
if (op->ch2 != -1)
|
||||||
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
|
||||||
return;
|
return;
|
||||||
case XPATH_OP_PREDICATE: {
|
case XPATH_OP_PREDICATE:
|
||||||
|
case XPATH_OP_FILTER: {
|
||||||
xmlXPathObjectPtr res;
|
xmlXPathObjectPtr res;
|
||||||
xmlXPathObjectPtr obj, tmp;
|
xmlXPathObjectPtr obj, tmp;
|
||||||
xmlNodeSetPtr newset = NULL;
|
xmlNodeSetPtr newset = NULL;
|
||||||
@ -7315,6 +7371,8 @@ xmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) {
|
|||||||
return(res->floatval == ctxt->proximityPosition);
|
return(res->floatval == ctxt->proximityPosition);
|
||||||
case XPATH_NODESET:
|
case XPATH_NODESET:
|
||||||
case XPATH_XSLT_TREE:
|
case XPATH_XSLT_TREE:
|
||||||
|
if (res->nodesetval == NULL)
|
||||||
|
return(0);
|
||||||
return(res->nodesetval->nodeNr != 0);
|
return(res->nodesetval->nodeNr != 0);
|
||||||
case XPATH_STRING:
|
case XPATH_STRING:
|
||||||
return((res->stringval != NULL) &&
|
return((res->stringval != NULL) &&
|
||||||
|
Loading…
x
Reference in New Issue
Block a user