xml2-replacements.sql
application/octet-stream
Filename: xml2-replacements.sql
Type: application/octet-stream
Part: 0
Message:
Re: remove contrib/xml2
-- Does NOT support parameters, as I don't need them for my project, but it
-- should be simple to add support for them.
CREATE OR REPLACE FUNCTION xslt_process(TEXT, TEXT) RETURNS TEXT AS $func$
use strict;
use XML::LibXSLT;
use XML::LibXML;
my $doc = shift;
my $xslt = shift;
# The following approach uses the older XML::LibXML 1.69 / XML::LibXSLT 1.68
# methods of parsing XML documents and stylesheets, in the hopes of broader
# compatibility with distributions
my $parser = $_SHARED{'_xslt_process'}{parsers}{xml} || XML::LibXML->new();
# Cache the XML parser, if we do not already have one
$_SHARED{'_xslt_process'}{parsers}{xml} = $parser
unless ($_SHARED{'_xslt_process'}{parsers}{xml});
my $xslt_parser = $_SHARED{'_xslt_process'}{parsers}{xslt} || XML::LibXSLT->new();
# Cache the XSLT processor, if we do not already have one
$_SHARED{'_xslt_process'}{parsers}{xslt} = $xslt_parser
unless ($_SHARED{'_xslt_process'}{parsers}{xslt});
my $stylesheet = $_SHARED{'_xslt_process'}{stylesheets}{$xslt} ||
$xslt_parser->parse_stylesheet( $parser->parse_string($xslt) );
$_SHARED{'_xslt_process'}{stylesheets}{$xslt} = $stylesheet
unless ($_SHARED{'_xslt_process'}{stylesheets}{$xslt});
return $stylesheet->output_string(
$stylesheet->transform(
$parser->parse_string($doc)
)
);
$func$ LANGUAGE PLPERLU STRICT IMMUTABLE;
CREATE OR REPLACE FUNCTION EXPLODE_ARRAY(anyarray) RETURNS SETOF anyelement AS $BODY$
SELECT ($1)[s] FROM generate_series(1, array_upper($1, 1)) AS s;
$BODY$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION xpath_table ( key TEXT, document_field TEXT, relation_name TEXT, xpaths TEXT, criteria TEXT ) RETURNS SETOF RECORD AS $func$
DECLARE
xpath_list TEXT[];
select_list TEXT[];
q TEXT;
out_record RECORD;
BEGIN
xpath_list := STRING_TO_ARRAY( xpaths, '|' );
select_list := ARRAY_APPEND( select_list, key || '::INT' );
FOR i IN 1 .. ARRAY_UPPER(xpath_list,1) LOOP
select_list := ARRAY_APPEND(
select_list,
$sel$ EXPLODE_ARRAY(
XPATH(
$sel$ || quote_literal( CASE WHEN xpath_list[i] ~ $re$/[^/[]*@[^/]+$$re$ THEN xpath_list[i] ELSE xpath_list[i] || '//text()' END ) || $sel$,
$sel$ || document_field || $sel$
)::TEXT[]
)$sel$
);
END LOOP;
q := $q$SELECT $q$ || ARRAY_TO_STRING( select_list, ', ' ) || $q$ FROM $q$ || relation_name || $q$ WHERE $q$ || criteria;
-- RAISE NOTICE 'query: %', q;
FOR out_record IN EXECUTE q LOOP
RETURN NEXT out_record;
END LOOP;
RETURN;
END;
$func$ LANGUAGE PLPGSQL;