diff --git a/contrib/xml2/expected/xml2.out b/contrib/xml2/expected/xml2.out index 74896b08020b2134e7f3d93a7035bb37bf909fb3..53b8064cc345474eb9d797e096753846769a0eb2 100644 --- a/contrib/xml2/expected/xml2.out +++ b/contrib/xml2/expected/xml2.out @@ -145,3 +145,71 @@ values Value</attribute></attributes>'); create index idx_xpath on t1 ( xpath_string ('/attributes/attribute[@name="attr_1"]/text()', xml_data::text)); +SELECT xslt_process('<employee><name>cim</name><age>30</age><pay>400</pay></employee>'::text, $$<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> + <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> + <xsl:strip-space elements="*"/> + <xsl:param name="n1"/> + <xsl:param name="n2"/> + <xsl:param name="n3"/> + <xsl:param name="n4"/> + <xsl:param name="n5" select="'me'"/> + <xsl:template match="*"> + <xsl:element name="samples"> + <xsl:element name="sample"> + <xsl:value-of select="$n1"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n2"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n3"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n4"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n5"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n6"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n7"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n8"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n9"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n10"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n11"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n12"/> + </xsl:element> + </xsl:element> + </xsl:template> +</xsl:stylesheet>$$::text, 'n1="v1",n2="v2",n3="v3",n4="v4",n5="v5",n6="v6",n7="v7",n8="v8",n9="v9",n10="v10",n11="v11",n12="v12"'::text); + xslt_process +------------------------ + <samples> + + <sample>v1</sample> + + <sample>v2</sample> + + <sample>v3</sample> + + <sample>v4</sample> + + <sample>v5</sample> + + <sample>v6</sample> + + <sample>v7</sample> + + <sample>v8</sample> + + <sample>v9</sample> + + <sample>v10</sample>+ + <sample>v11</sample>+ + <sample>v12</sample>+ + </samples> + + +(1 row) + diff --git a/contrib/xml2/expected/xml2_1.out b/contrib/xml2/expected/xml2_1.out index 083fc3b2cac0810992c52a07faffa7d1ccd56373..b465ea27b631ee7ef0ce5863fc286dc4630e14c8 100644 --- a/contrib/xml2/expected/xml2_1.out +++ b/contrib/xml2/expected/xml2_1.out @@ -107,3 +107,53 @@ values Value</attribute></attributes>'); create index idx_xpath on t1 ( xpath_string ('/attributes/attribute[@name="attr_1"]/text()', xml_data::text)); +SELECT xslt_process('<employee><name>cim</name><age>30</age><pay>400</pay></employee>'::text, $$<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> + <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> + <xsl:strip-space elements="*"/> + <xsl:param name="n1"/> + <xsl:param name="n2"/> + <xsl:param name="n3"/> + <xsl:param name="n4"/> + <xsl:param name="n5" select="'me'"/> + <xsl:template match="*"> + <xsl:element name="samples"> + <xsl:element name="sample"> + <xsl:value-of select="$n1"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n2"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n3"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n4"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n5"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n6"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n7"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n8"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n9"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n10"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n11"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n12"/> + </xsl:element> + </xsl:element> + </xsl:template> +</xsl:stylesheet>$$::text, 'n1="v1",n2="v2",n3="v3",n4="v4",n5="v5",n6="v6",n7="v7",n8="v8",n9="v9",n10="v10",n11="v11",n12="v12"'::text); +ERROR: xslt_process() is not available without libxslt diff --git a/contrib/xml2/sql/xml2.sql b/contrib/xml2/sql/xml2.sql index 73723b6be1026a5c17c73baccbf10bb945a90716..202a72baedc4050d855f329c58cf75eb2bd79741 100644 --- a/contrib/xml2/sql/xml2.sql +++ b/contrib/xml2/sql/xml2.sql @@ -80,3 +80,53 @@ Value</attribute></attributes>'); create index idx_xpath on t1 ( xpath_string ('/attributes/attribute[@name="attr_1"]/text()', xml_data::text)); + +SELECT xslt_process('<employee><name>cim</name><age>30</age><pay>400</pay></employee>'::text, $$<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> + <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/> + <xsl:strip-space elements="*"/> + <xsl:param name="n1"/> + <xsl:param name="n2"/> + <xsl:param name="n3"/> + <xsl:param name="n4"/> + <xsl:param name="n5" select="'me'"/> + <xsl:template match="*"> + <xsl:element name="samples"> + <xsl:element name="sample"> + <xsl:value-of select="$n1"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n2"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n3"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n4"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n5"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n6"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n7"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n8"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n9"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n10"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n11"/> + </xsl:element> + <xsl:element name="sample"> + <xsl:value-of select="$n12"/> + </xsl:element> + </xsl:element> + </xsl:template> +</xsl:stylesheet>$$::text, 'n1="v1",n2="v2",n3="v3",n4="v4",n5="v5",n6="v6",n7="v7",n8="v8",n9="v9",n10="v10",n11="v11",n12="v12"'::text); diff --git a/contrib/xml2/xslt_proc.c b/contrib/xml2/xslt_proc.c index 4c80732bb8bb5a119a6c8bb75dc881488e8c4337..158345b20b3720002dd1cc389526a7a5a753310e 100644 --- a/contrib/xml2/xslt_proc.c +++ b/contrib/xml2/xslt_proc.c @@ -1,5 +1,5 @@ /* - * $PostgreSQL: pgsql/contrib/xml2/xslt_proc.c,v 1.21 2010/07/06 19:18:55 momjian Exp $ + * $PostgreSQL: pgsql/contrib/xml2/xslt_proc.c,v 1.22 2010/08/10 23:02:00 tgl Exp $ * * XSLT processing functions (requiring libxslt) * @@ -41,9 +41,8 @@ Datum xslt_process(PG_FUNCTION_ARGS); extern void pgxml_parser_init(void); /* local defs */ -static void parse_params(const char **params, text *paramstr); +static const char **parse_params(text *paramstr); -#define MAXPARAMS 20 /* must be even, see parse_params() */ #endif /* USE_LIBXSLT */ @@ -57,7 +56,7 @@ xslt_process(PG_FUNCTION_ARGS) text *doct = PG_GETARG_TEXT_P(0); text *ssheet = PG_GETARG_TEXT_P(1); text *paramstr; - const char *params[MAXPARAMS + 1]; /* +1 for the terminator */ + const char **params; xsltStylesheetPtr stylesheet = NULL; xmlDocPtr doctree; xmlDocPtr restree; @@ -69,11 +68,14 @@ xslt_process(PG_FUNCTION_ARGS) if (fcinfo->nargs == 3) { paramstr = PG_GETARG_TEXT_P(2); - parse_params(params, paramstr); + params = parse_params(paramstr); } else + { /* No parameters */ + params = (const char **) palloc(sizeof(char *)); params[0] = NULL; + } /* Setup parser */ pgxml_parser_init(); @@ -139,22 +141,34 @@ xslt_process(PG_FUNCTION_ARGS) #ifdef USE_LIBXSLT -static void -parse_params(const char **params, text *paramstr) +static const char ** +parse_params(text *paramstr) { char *pos; char *pstr; - int i; char *nvsep = "="; char *itsep = ","; + const char **params; + int max_params; + int nparams; pstr = text_to_cstring(paramstr); + max_params = 20; /* must be even! */ + params = (const char **) palloc((max_params + 1) * sizeof(char *)); + nparams = 0; + pos = pstr; - for (i = 0; i < MAXPARAMS; i++) + while (*pos != '\0') { - params[i] = pos; + if (nparams >= max_params) + { + max_params *= 2; + params = (const char **) repalloc(params, + (max_params + 1) * sizeof(char *)); + } + params[nparams++] = pos; pos = strstr(pos, nvsep); if (pos != NULL) { @@ -164,13 +178,12 @@ parse_params(const char **params, text *paramstr) else { /* No equal sign, so ignore this "parameter" */ - /* We'll reset params[i] to NULL below the loop */ + nparams--; break; } - /* Value */ - i++; - /* since MAXPARAMS is even, we still have i < MAXPARAMS */ - params[i] = pos; + + /* since max_params is even, we still have nparams < max_params */ + params[nparams++] = pos; pos = strstr(pos, itsep); if (pos != NULL) { @@ -178,13 +191,13 @@ parse_params(const char **params, text *paramstr) pos++; } else - { - i++; break; - } } - params[i] = NULL; + /* Add the terminator marker; we left room for it in the palloc's */ + params[nparams] = NULL; + + return params; } #endif /* USE_LIBXSLT */