diff options
Diffstat (limited to 'pattern.c')
-rw-r--r-- | pattern.c | 129 |
1 files changed, 91 insertions, 38 deletions
@@ -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); } /** |