summaryrefslogtreecommitdiff
path: root/pattern.c
diff options
context:
space:
mode:
Diffstat (limited to 'pattern.c')
-rw-r--r--pattern.c129
1 files changed, 91 insertions, 38 deletions
diff --git a/pattern.c b/pattern.c
index 125e37c..a76a58c 100644
--- a/pattern.c
+++ b/pattern.c
@@ -139,7 +139,7 @@ struct _xmlPattern {
xmlDictPtr dict; /* the optional dictionary */
struct _xmlPattern *next; /* next pattern if | is used */
const xmlChar *pattern; /* the pattern */
- xmlPatternFlags flags; /* flags */
+ int flags; /* flags */
int nbStep;
int maxStep;
xmlStepOpPtr steps; /* ops for computation */
@@ -905,20 +905,26 @@ xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
* This is a namespace match
*/
token = xmlPatScanName(ctxt);
- for (i = 0;i < ctxt->nb_namespaces;i++) {
- if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
- URL = xmlStrdup(ctxt->namespaces[2 * i]);
- break;
+ if ((prefix[0] == 'x') &&
+ (prefix[1] == 'm') &&
+ (prefix[2] == 'l') &&
+ (prefix[3] == 0)) {
+ URL = xmlStrdup(XML_XML_NAMESPACE);
+ } else {
+ for (i = 0;i < ctxt->nb_namespaces;i++) {
+ if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
+ URL = xmlStrdup(ctxt->namespaces[2 * i]);
+ break;
+ }
+ }
+ if (i >= ctxt->nb_namespaces) {
+ ERROR5(NULL, NULL, NULL,
+ "xmlCompileAttributeTest : no namespace bound to prefix %s\n",
+ prefix);
+ ctxt->error = 1;
+ goto error;
}
}
- if (i >= ctxt->nb_namespaces) {
- ERROR5(NULL, NULL, NULL,
- "xmlCompileAttributeTest : no namespace bound to prefix %s\n",
- prefix);
- ctxt->error = 1;
- goto error;
- }
-
xmlFree(prefix);
if (token == NULL) {
if (CUR == '*') {
@@ -998,18 +1004,25 @@ xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
* This is a namespace match
*/
token = xmlPatScanName(ctxt);
- for (i = 0;i < ctxt->nb_namespaces;i++) {
- if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
- URL = xmlStrdup(ctxt->namespaces[2 * i]);
- break;
+ if ((prefix[0] == 'x') &&
+ (prefix[1] == 'm') &&
+ (prefix[2] == 'l') &&
+ (prefix[3] == 0)) {
+ URL = xmlStrdup(XML_XML_NAMESPACE);
+ } else {
+ for (i = 0;i < ctxt->nb_namespaces;i++) {
+ if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
+ URL = xmlStrdup(ctxt->namespaces[2 * i]);
+ break;
+ }
+ }
+ if (i >= ctxt->nb_namespaces) {
+ ERROR5(NULL, NULL, NULL,
+ "xmlCompileStepPattern : no namespace bound to prefix %s\n",
+ prefix);
+ ctxt->error = 1;
+ goto error;
}
- }
- if (i >= ctxt->nb_namespaces) {
- ERROR5(NULL, NULL, NULL,
- "xmlCompileStepPattern : no namespace bound to prefix %s\n",
- prefix);
- ctxt->error = 1;
- goto error;
}
xmlFree(prefix);
if (token == NULL) {
@@ -1051,18 +1064,25 @@ xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
* This is a namespace match
*/
token = xmlPatScanName(ctxt);
- for (i = 0;i < ctxt->nb_namespaces;i++) {
- if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
- URL = xmlStrdup(ctxt->namespaces[2 * i]);
- break;
+ if ((prefix[0] == 'x') &&
+ (prefix[1] == 'm') &&
+ (prefix[2] == 'l') &&
+ (prefix[3] == 0)) {
+ URL = xmlStrdup(XML_XML_NAMESPACE);
+ } else {
+ for (i = 0;i < ctxt->nb_namespaces;i++) {
+ if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
+ URL = xmlStrdup(ctxt->namespaces[2 * i]);
+ break;
+ }
+ }
+ if (i >= ctxt->nb_namespaces) {
+ ERROR5(NULL, NULL, NULL,
+ "xmlCompileStepPattern : no namespace bound "
+ "to prefix %s\n", prefix);
+ ctxt->error = 1;
+ goto error;
}
- }
- if (i >= ctxt->nb_namespaces) {
- ERROR5(NULL, NULL, NULL,
- "xmlCompileStepPattern : no namespace bound "
- "to prefix %s\n", prefix);
- ctxt->error = 1;
- goto error;
}
xmlFree(prefix);
if (token == NULL) {
@@ -1615,6 +1635,14 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream,
*/
if (comp->nbStep == 0) {
/*
+ * / and . are handled at the XPath node set creation
+ * level by checking min depth
+ */
+ if (stream->flags & XML_PATTERN_XPATH) {
+ stream = stream->next;
+ continue; /* while */
+ }
+ /*
* For non-pattern like evaluation like XML Schema IDCs
* or traditional XPath expressions, this will match if
* we are at the first level only, otherwise on every level.
@@ -1934,7 +1962,7 @@ xmlStreamPop(xmlStreamCtxtPtr stream) {
* xmlPatterncompile:
* @pattern: the pattern to compile
* @dict: an optional dictionary for interned strings
- * @flags: compilation flags, undefined yet
+ * @flags: compilation flags, see xmlPatternFlags
* @namespaces: the prefix definitions, array of [URI, prefix] or NULL
*
* Compile a pattern.
@@ -1942,8 +1970,7 @@ xmlStreamPop(xmlStreamCtxtPtr stream) {
* Returns the compiled form of the pattern or NULL in case of error
*/
xmlPatternPtr
-xmlPatterncompile(const xmlChar *pattern, xmlDict *dict,
- xmlPatternFlags flags,
+xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags,
const xmlChar **namespaces) {
xmlPatternPtr ret = NULL, cur;
xmlPatParserContextPtr ctxt = NULL;
@@ -2138,7 +2165,33 @@ xmlPatternMaxDepth(xmlPatternPtr comp) {
comp = comp->next;
}
return(ret);
+}
+/**
+ * xmlPatternMinDepth:
+ * @comp: the precompiled pattern
+ *
+ * Check the minimum depth reachable by a pattern, 0 mean the / or . are
+ * part of the set.
+ *
+ * Returns -1 in case of error otherwise the depth,
+ *
+ */
+int
+xmlPatternMinDepth(xmlPatternPtr comp) {
+ int ret = 12345678;
+ if (comp == NULL)
+ return(-1);
+ while (comp != NULL) {
+ if (comp->stream == NULL)
+ return(-1);
+ if (comp->stream->nbStep < ret)
+ ret = comp->stream->nbStep;
+ if (ret == 0)
+ return(0);
+ comp = comp->next;
+ }
+ return(ret);
}
/**