static int WFS_ExprDumpGmlObjectIdFilter(CPLString& osFilter, const Expr* expr, int bUseFeatureId, int bGmlObjectIdNeedsGMLPrefix, int nVersion) { if (expr->eType == TOKEN_EQUAL && expr->expr1->eType == TOKEN_VAR_NAME && EQUAL(expr->expr1->pszVal, "gml_id") && expr->expr2->eType == TOKEN_LITERAL) { if (bUseFeatureId) osFilter += "<FeatureId fid=\""; else if (nVersion >= 200) osFilter += "<ResourceId rid=\""; else if (!bGmlObjectIdNeedsGMLPrefix) osFilter += "<GmlObjectId id=\""; else osFilter += "<GmlObjectId gml:id=\""; if (expr->expr2->pszVal[0] == '\'' || expr->expr2->pszVal[0] == '"') { CPLString osVal(expr->expr2->pszVal + 1); osVal.resize(osVal.size() - 1); osFilter += osVal; } else osFilter += expr->expr2->pszVal; osFilter += "\"/>"; return TRUE; } else if (expr->eType == TOKEN_OR) { return WFS_ExprDumpGmlObjectIdFilter(osFilter, expr->expr1, bUseFeatureId, bGmlObjectIdNeedsGMLPrefix, nVersion) && WFS_ExprDumpGmlObjectIdFilter(osFilter, expr->expr2, bUseFeatureId, bGmlObjectIdNeedsGMLPrefix, nVersion); } return FALSE; }
static int WFS_ExprDumpAsOGCFilter(CPLString& osFilter, const Expr* expr, int bExpectBinary, ExprDumpFilterOptions* psOptions) { switch(expr->eType) { case TOKEN_VAR_NAME: if (bExpectBinary) return FALSE; /* Special fields not understood by server */ if (EQUAL(expr->pszVal, "gml_id") || EQUAL(expr->pszVal, "FID") || EQUAL(expr->pszVal, "OGR_GEOMETRY") || EQUAL(expr->pszVal, "OGR_GEOM_WKT") || EQUAL(expr->pszVal, "OGR_GEOM_AREA") || EQUAL(expr->pszVal, "OGR_STYLE")) return FALSE; if (psOptions->nVersion >= 200) osFilter += "<ValueReference>"; else osFilter += "<PropertyName>"; if (expr->pszVal[0] == '\'' || expr->pszVal[0] == '"') { CPLString osVal(expr->pszVal + 1); osVal.resize(osVal.size() - 1); osFilter += osVal; } else osFilter += expr->pszVal; if (psOptions->nVersion >= 200) osFilter += "</ValueReference>"; else osFilter += "</PropertyName>"; break; case TOKEN_LITERAL: if (bExpectBinary) return FALSE; osFilter += "<Literal>"; if (expr->pszVal[0] == '\'' || expr->pszVal[0] == '"') { CPLString osVal(expr->pszVal + 1); osVal.resize(osVal.size() - 1); osFilter += osVal; } else osFilter += expr->pszVal; osFilter += "</Literal>"; break; case TOKEN_NOT: osFilter += "<Not>"; if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr1, TRUE, psOptions)) return FALSE; osFilter += "</Not>"; break; case TOKEN_LIKE: { CPLString osVal; char ch; char firstCh = 0; int i; if (psOptions->nVersion == 100) osFilter += "<PropertyIsLike wildCard='*' singleChar='_' escape='!'>"; else osFilter += "<PropertyIsLike wildCard='*' singleChar='_' escapeChar='!'>"; if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr1, FALSE, psOptions)) return FALSE; if (expr->expr2->eType != TOKEN_LITERAL) return FALSE; osFilter += "<Literal>"; /* Escape value according to above special characters */ /* For URL compatibility reason, we remap the OGR SQL '%' wildchard into '*' */ i = 0; ch = expr->expr2->pszVal[i]; if (ch == '\'' || ch == '"') { firstCh = ch; i ++; } for(;(ch = expr->expr2->pszVal[i]) != '\0';i++) { if (ch == '%') osVal += "*"; else if (ch == '!') osVal += "!!"; else if (ch == '*') osVal += "!*"; else if (ch == firstCh && expr->expr2->pszVal[i + 1] == 0) break; else { char ach[2]; ach[0] = ch; ach[1] = 0; osVal += ach; } } osFilter += osVal; osFilter += "</Literal>"; osFilter += "</PropertyIsLike>"; break; } case TOKEN_EQUAL: case TOKEN_NOT_EQUAL: case TOKEN_LESSER_OR_EQUAL: case TOKEN_LESSER: case TOKEN_GREATER_OR_EQUAL: case TOKEN_GREATER: { if (expr->eType == TOKEN_EQUAL && expr->expr2->eType == TOKEN_LITERAL && EQUAL(expr->expr2->pszVal, "NULL")) { osFilter += "<PropertyIsNull>"; if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr1, FALSE, psOptions)) return FALSE; osFilter += "</PropertyIsNull>"; psOptions->bOutNeedsNullCheck = TRUE; break; } if (expr->eType == TOKEN_NOT_EQUAL && expr->expr2->eType == TOKEN_LITERAL && EQUAL(expr->expr2->pszVal, "NULL")) { osFilter += "<Not><PropertyIsNull>"; if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr1, FALSE, psOptions)) return FALSE; osFilter += "</PropertyIsNull></Not>"; psOptions->bOutNeedsNullCheck = TRUE; break; } TokenType eType = expr->eType; int bAddClosingNot = FALSE; if (!psOptions->bPropertyIsNotEqualToSupported && eType == TOKEN_NOT_EQUAL) { osFilter += "<Not>"; eType = TOKEN_EQUAL; bAddClosingNot = TRUE; } const char* pszName = NULL; switch(eType) { case TOKEN_EQUAL: pszName = "PropertyIsEqualTo"; break; case TOKEN_NOT_EQUAL: pszName = "PropertyIsNotEqualTo"; break; case TOKEN_LESSER_OR_EQUAL: pszName = "PropertyIsLessThanOrEqualTo"; break; case TOKEN_LESSER: pszName = "PropertyIsLessThan"; break; case TOKEN_GREATER_OR_EQUAL:pszName = "PropertyIsGreaterThanOrEqualTo"; break; case TOKEN_GREATER: pszName = "PropertyIsGreaterThan"; break; default: break; } osFilter += "<"; osFilter += pszName; osFilter += ">"; if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr1, FALSE, psOptions)) return FALSE; if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr2, FALSE, psOptions)) return FALSE; osFilter += "</"; osFilter += pszName; osFilter += ">"; if (bAddClosingNot) osFilter += "</Not>"; break; } case TOKEN_AND: case TOKEN_OR: { const char* pszName = (expr->eType == TOKEN_AND) ? "And" : "Or"; osFilter += "<"; osFilter += pszName; osFilter += ">"; if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr1, TRUE, psOptions)) return FALSE; if (!WFS_ExprDumpAsOGCFilter(osFilter, expr->expr2, TRUE, psOptions)) return FALSE; osFilter += "</"; osFilter += pszName; osFilter += ">"; break; } default: return FALSE; } return TRUE; }