* Common code for xpath() and xmlexists() * * Evaluate XPath expression and return number of nodes in res_nitems * and array of XML values in astate. Either of those pointers can be * NULL if the corresponding result isn't wanted. * * It is up to the user to ensure that the XML passed is in fact * an XML document - XPath doesn't work easily on fragments without * a context node being know
| 3987 | * a context node being known. |
| 3988 | */ |
| 3989 | static void |
| 3990 | xpath_internal(text *xpath_expr_text, xmltype *data, ArrayType *namespaces, |
| 3991 | int *res_nitems, ArrayBuildState *astate) |
| 3992 | { |
| 3993 | PgXmlErrorContext *xmlerrcxt; |
| 3994 | volatile xmlParserCtxtPtr ctxt = NULL; |
| 3995 | volatile xmlDocPtr doc = NULL; |
| 3996 | volatile xmlXPathContextPtr xpathctx = NULL; |
| 3997 | volatile xmlXPathCompExprPtr xpathcomp = NULL; |
| 3998 | volatile xmlXPathObjectPtr xpathobj = NULL; |
| 3999 | char *datastr; |
| 4000 | int32 len; |
| 4001 | int32 xpath_len; |
| 4002 | xmlChar *string; |
| 4003 | xmlChar *xpath_expr; |
| 4004 | size_t xmldecl_len = 0; |
| 4005 | int i; |
| 4006 | int ndim; |
| 4007 | Datum *ns_names_uris; |
| 4008 | bool *ns_names_uris_nulls; |
| 4009 | int ns_count; |
| 4010 | |
| 4011 | /* |
| 4012 | * Namespace mappings are passed as text[]. If an empty array is passed |
| 4013 | * (ndim = 0, "0-dimensional"), then there are no namespace mappings. |
| 4014 | * Else, a 2-dimensional array with length of the second axis being equal |
| 4015 | * to 2 should be passed, i.e., every subarray contains 2 elements, the |
| 4016 | * first element defining the name, the second one the URI. Example: |
| 4017 | * ARRAY[ARRAY['myns', 'http://example.com'], ARRAY['myns2', |
| 4018 | * 'http://example2.com']]. |
| 4019 | */ |
| 4020 | ndim = namespaces ? ARR_NDIM(namespaces) : 0; |
| 4021 | if (ndim != 0) |
| 4022 | { |
| 4023 | int *dims; |
| 4024 | |
| 4025 | dims = ARR_DIMS(namespaces); |
| 4026 | |
| 4027 | if (ndim != 2 || dims[1] != 2) |
| 4028 | ereport(ERROR, |
| 4029 | (errcode(ERRCODE_DATA_EXCEPTION), |
| 4030 | errmsg("invalid array for XML namespace mapping"), |
| 4031 | errdetail("The array must be two-dimensional with length of the second axis equal to 2."))); |
| 4032 | |
| 4033 | Assert(ARR_ELEMTYPE(namespaces) == TEXTOID); |
| 4034 | |
| 4035 | deconstruct_array(namespaces, TEXTOID, -1, false, TYPALIGN_INT, |
| 4036 | &ns_names_uris, &ns_names_uris_nulls, |
| 4037 | &ns_count); |
| 4038 | |
| 4039 | Assert((ns_count % 2) == 0); /* checked above */ |
| 4040 | ns_count /= 2; /* count pairs only */ |
| 4041 | } |
| 4042 | else |
| 4043 | { |
| 4044 | ns_names_uris = NULL; |
| 4045 | ns_names_uris_nulls = NULL; |
| 4046 | ns_count = 0; |
no test coverage detected