File: daps-xslt

package info (click to toggle)
daps 3.3.2%2Bcleaned1-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,540 kB
  • sloc: xml: 9,773; sh: 3,059; python: 1,322; lisp: 380; makefile: 239
file content (426 lines) | stat: -rwxr-xr-x 14,688 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
#!/bin/bash
#
# Copyright (C) 2012-2020 SUSE Software Solutions Germany GmbH
#
# Authors:
# Kilian Petsch <kpetsch@suse.de>
# Frank Sundermeyer <fsundermeyer at opensuse dot org>
#
# Wrapper script which lets you use either xsltproc or saxon6
# with the same command
#
# NOTE:
#
# Setting the catalog for the resolver
#
# xsltproc and saxon have different ways to determine which catalogs to use
# for resolving Identifiers, URI, etc
# * xsltproc: reads $XML_CATALOG_FILES
# * saxon: uses a JAVA resolver class which uses the catalogs= setting in the
#          system wide CatalogManager.properties file
#          (e.g. /etc/java/resolver/CatalogManager.properties)
#
# DAPS sets and exports $XML_CATALOG_FILES, so we will use these settings for
# this wrapper as well (for both, xsltproc and saxon). Catalogs added with
# --catalog will be added to the existing $XML_CATALOG_FILES
#
# If this script is called from the command-line, it will also use
# $XML_CATALOG_FILES. If not set (probably the case on systems with no
# xsltproc), saxon will use the defaults from CatalogManager.properties
#
# If using xsltproc and if no additional catalogs have been specified with
# --catalog, there is nothing to do, because XML_CATALOG_FILES is either set
# system wide or exported by DAPS
#
# Saxon9 support (see ticket #94)
#

ME="$(basename "$0")"
XSLTPROC="/usr/bin/xsltproc"
SAXON="/usr/bin/saxon"
# TODO: we may need to change this path with configure
DBXSLT=/usr/share/xml/docbook/stylesheet/nwalsh/current

unset DEBUG ERR_CODE OUTPUT PARAMETERS PARMS SAXON6_ARGS STRPARMS STYLESHEET
unset XINCLUDE XMLFILE XML_TMP_FILE XSLTPROC_ARGS

# list of stringparams
declare -a STRPARMS
# list of params
declare -a PARMS
# final list of stringparams/params
declare -a PARAMETERS

# Help function to preserve readability of the while loop
function usage {
    cat <<EOF_helptext
Usage: daps-xslt -o <OUTPUTFILE> -s <STYLESHEET> -f <XMLDOCUMENT> [OPTIONS] <XSLTPROCESSOR>
Wrapper script for DAPS to use either xsltproc or saxon as an XSLT processor.

Mandatory parameters:
 --stylesheet=STYLESHEET,     Path to the stylesheet to be used. Mandatory.

 --file=XMLDOCUMENT,          XML document to which the stylesheet will be
 -f XMLDOCUMENT               applied. Mandatory.

 --output=OUTPUTFILE,         Specify a file for output. If not used, output
 - o OUTPUTFILE               goes to STDOUT. Optional.


Optional parameters:
 --catalogs="CATALOGS"        Define a space-separated list of XML catalogs
                              for resolving identifiersr; to be used in addition
                              to the system wide default catalog.

 --debug                      Activate a debugging mode (verbose).

 --help, -h                   Print this help.

 --param="KEY=VALUE"          Pass a parameter KEY with the numeric value VALUE
                              to the stylesheet. The key-value pair must be
                              written as KEY=VALUE. Use --stringparam to pass
                              string values. You may pass up to 32 key/value
                              pairs by using this parameter multiple times. If
                              the same key/value pair is passed more than once,
                              the last one "wins".
                              Optional.

 --saxon6_args="LIST"         saxon6 specific options (see saxon6 --help).
                              "LIST" is a list of options specified in the
                              same way as when calling saxon6 directly.
                              If double-quotes need to be passed on, LIST needs
                              to be put in single quotes.
                              This parameter is ignored when using xsltproc.

 --stringparam='"KEY=VALUE"'  Pass a parameter KEY with the string value VALUE
                              to the stylesheet. The key-value pair must be
                              written as '"KEY=VALUE"' (mind the quoting!).
                              Use --param to pass numeric values.
                              You may pass multiple key/value pairs up to a
                              maximum of 32. If the same key/value pair is
                              passed more than once, the last one "wins".
                              Optional.

 --xsltproc_args="LIST"       xsltproc specific options (see man xsltptroc).
                              "LIST" is a list of options specified in the same
                              way as when calling xsltproc directly.
                              If double-quotes need to be passed on, LIST needs
                              to be put in single quotes.
                              This parameter is ignored when using saxon.

 --xinclude                   Process the input document using the XInclude
                              specification.


XSLT processor:
  Define the XSLT processor, xsltproc or saxon6 (mandatory) and
  processor-specific options (optional, see the respective man pages
  for details).
EOF_helptext
    exit
}

function cleanup {
    [[ -f $XML_TMP_FILE ]] && rm -f "$XML_TMP_FILE"
}

function exit_on_error {
    echo -e "ERROR: $1" >&2
    cleanup
    exit 1;
}

function run-saxon {
    local CATALOGS SAXON_ARGS
    # TODO fs 2012-11-24
    # check whether this works with other distributions
    # -dependencies in spec-file may need to be enhanced because of
    #  the additional jars

    # replace [:space:] with ";" but retain spaces in filenames
    CATALOGS="${XML_CATALOG_FILES// \//;/}"

    if [[ -z "$DEBUG" ]]; then
        # Recover silently from recoverable errors
        SAXON_ARGS="-w0 $SAXON_ARGS"
    fi

    # if the stylesheet location is a link, saxon needs -u
    if [[ urn: = "${STYLESHEET:0:4}" || http: = "${STYLESHEET:0:5}" || file: = "${STYLESHEET:0:5}" ]]; then
        SAXON_ARGS="$SAXON_ARGS -u"
    fi

   # Add the DocBook extensions to the CLASSPATH

    CLASSPATH="${DBXSLT}/extensions/saxon65.jar:$CLASSPATH"

    # A local CatalogManager.properties file is stored in
    # ${DAPSROOT}/etc/
    [[ -n $DAPSROOT ]] && CLASSPATH="${DAPSROOT}/etc/:$CLASSPATH"

    # Additional JAR files
    ADDITIONAL_JARS="xml-commons-resolver12.jar"

    # Add catalogs, if specified
    [[ -n "$CATALOGS" ]] && ADDITIONAL_FLAGS="$ADDITIONAL_FLAGS -Dxml.catalog.files=$CATALOGS"

    # enable XIncludes (by adding Xerces) if requested
    if [[ -n "$XINCLUDE" ]]; then
        ADDITIONAL_JARS="$ADDITIONAL_JARS xerces-j2.jar xerces-j2-xml-apis.jar"
        ADDITIONAL_FLAGS="$ADDITIONAL_FLAGS \
-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl \
-Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl \
-Dorg.apache.xerces.xni.parser.XMLParserConfiguration=org.apache.xerces.parsers.XIncludeParserConfiguration"
    fi

    export ADDITIONAL_FLAGS ADDITIONAL_JARS CLASSPATH

    if [[ -n "$DEBUG" ]]; then
        cat <<EOF
---------------------------------------------------------"
Running $ME with the following parameters:
  CLASSPATH="$CLASSPATH"
  XML_CATALOG_FILES="$XML_CATALOG_FILES"
  CATALOGS="$CATALOGS"
  ADDITIONAL_JARS="$ADDITIONAL_JARS"
  ADDITIONAL_FLAGS="$ADDITIONAL_FLAGS"
  $SAXON $SAXON_ARGS $@"
---------------------------------------------------------
EOF
    fi
    eval "$SAXON $SAXON_ARGS $*"
}

process_params () {
    # Function to create a list of params and stringparams for xsltproc
    # This function ensure that we can pass a certain parameter twice, with
    # that last one specified taking precedence. This is needed to overwrite
    # stringparams already set in the makefiles.
    # Natively, xsltproc does not support specifying a parameter twice, so
    # something like xsltproc --param foo bar --param foo baz will result
    # in an error.
    # This function takes care that all key/value with the same key are
    # deleted, except the last one specified.
    #
    # This functions takes two parameters
    # * PREFIX which must be either "param" or "stringparam"
    # * a list of KEY=VALUE pairs (param(stringparam values passed to this
    #   script
    #

    local ELEM I KEY PREFIX RESULT SEEN STR_PAR VALUE
    local -a KEYLIST
    local -a PARAMLIST


    PREFIX=$1
    shift
    PARAMLIST=( "$@" )

    if [[ param != $PREFIX && stringparam != $PREFIX ]]; then
        exit_on_error "Error:\nFirst parameter when calling process_params must be \"param\" or \"stringparam\"!"
    fi

    # initialize KEYLIST with an empty value
    KEYLIST[0]=""

    for ((I=${#PARAMLIST[@]}-1; I>=0; I--)); do
        SEEN=0
        STR_PAR=${PARAMLIST[$I]}
        # get rid of the double quotes of stringparams
        # ${STR_PAR:1:-1} does not work with bash 3.2
        #
        STR_PAR=${STR_PAR#\"}
        STR_PAR=${STR_PAR%\"}
        # split into KEY/VALUE at first "="
        KEY=${STR_PAR%%=*} # delete "=VALUE" part
        if [[ stringparam = "$PREFIX" ]];then
            VALUE="\"${STR_PAR#*=}\"" # delete "KEY=" part
        else
            VALUE=${STR_PAR#*=}
        fi
        #
        # we need to stay Bash 3.x compatible, therefore no
        # associative arrays, but rather using a list

        for ELEM in "${KEYLIST[@]}"; do
            if [[ $KEY = "$ELEM" ]]; then
                SEEN=1
                break
            fi
        done
        if [[ 0 = "$SEEN" ]]; then
            KEYLIST+=("$KEY")
            RESULT="$RESULT --$PREFIX $KEY $VALUE"
        fi
    done
    echo "$RESULT"
}

piped_input () {
    XML_TMP_FILE=$(mktemp -q daps_xslt_input.XXXXXXXX) || exit_on_error "Could not save piped input into a temporary file"
    cat > "$XML_TMP_FILE"
    XMLFILE="$XML_TMP_FILE"
    [[ -s $XMLFILE ]] || exit_on_error "Did not get XML data via pipe"
}

#----------------------------------------------------------------------------
# MAIN

# enable interruption/abortion via Ctrl-Z/Ctrl-C
trap "exit_on_error '\nCaught SIGTERM/SIGINT'" SIGTERM SIGINT
trap "cleanup" ERR EXIT

[[ -z "$1" ]] && usage

export POSIXLY_CORRECT=1
ARGS=$(getopt -o "f:hno:s:v" -l "catalogs:,debug,file:,help,nonet,novalid,output:,param:,saxon6_args:,stringparam:,stylesheet:,xinclude,xsltproc_args:" -n "$ME" -- "$@")

eval set -- "$ARGS"

while true; do
    case "$1" in
        --catalogs)
            XML_CATALOG_FILES="$2 $XML_CATALOG_FILES";
            export XML_CATALOG_FILES
            shift 2;;
        --debug)
            DEBUG=1
            export VERBOSE=1
            shift;;
        -f|--file)
            XMLFILE="$2"
            shift 2;;
        -h|--help)
            usage
            exit 0;;
        -o|--output)
            OUTPUT="-o $2"
            shift 2;;
        --param|--stringparam)
            # Slightly hacky:
            # While xsltproc may make a few memory optimizations based on
            # whether it receives --stringparam or --param parameters, XSLT
            # itself is not statically typed in any sense and does not need the
            # differentiation.
            # However, if you specify --param foo=1 and --stringparam "foo=1",
            # xsltproc will exit with an error, because "$foo" has been declared
            # twice. Changing process_params to correct this properly (keeping
            # separate, but deduplicated against each other lists of params and
            # stringparams) would be a major effort, so we will simply treat
            # everything as a --stringparam by only writing to
            # STRPARMS. This fixes DAPS issue #589.

            # The precedence of parameters is slightly buggy: parameters
            # specified as --stringparam will always win over plain --param
            # (stringparam is defined after param in the getopt optstring
            # above). Besides that, the last parameter specified on the
            # command line wins.

            # check for equal sign
            if [[ $2 =~ = ]]; then
                STRPARMS+=("\"$2\"")
            else
                exit_on_error "--param requires \"KEY=VALUE\" as parameter"
            fi
            shift 2;;
        -s|--stylesheet)
            STYLESHEET="$2"
            shift 2
            ;;
        --saxon6_args)
            SAXON6_ARGS="$2"
            shift 2
            ;;
        -x|--xinclude)
            XINCLUDE="--xinclude"
            shift;;
        --xsltproc_args)
            XSLTPROC_ARGS="$2"
            shift 2
            ;;
        --)
            shift
            break;;
        *) exit_on_error "Internal error!" ;;
    esac
done

unset POSIXLY_CORRECT

#-----
# Getting the xsltprocessor
#
if [[ $1 =~ xsltproc || $1 =~ saxon ]]; then
    PROCESSOR=$1
    shift;
else
    exit_on_error "Invalid XSLT processor: must be either xsltproc or saxon"
    exit 1;
fi

# ???
#PROCESSOR_ARGS="$*"

#-----
# Check if stylesheet has been specified
#
[[ -z "$STYLESHEET" ]] && exit_on_error "you must specify a stylesheet with --stylesheet <STYLESHEET>"

#----
# Get input from pipe (in case a pipe exists)
#
# Not needed ATM since we always use --file in DAPS
# commenting the code in case it is needed in the future
# BEWARE:
# This code covers the following cases:
# * cat foo | daps_xslt
# * daps_xslt --file
# * daps_xslt < foo
# Input coming from a pseudo-Terminal (ok, this is a rare cornercase) is
# not supported (cat foo > /dev/pts1 && daps_xslt < /dev/pts/1 )

if [[ -z "$XMLFILE" ]]; then
    if [[ -p /dev/stdin ]]; then
        # pipe
        piped_input
    elif [[ ! -t 0 && ! -p /dev/stdin ]]; then
        # redirected with < foo
        piped_input
    else
        exit_on_error "You must either specify an XML file with --file or pipe it into $ME"
    fi
fi

#-----
# run the XSLT processor
#
if [[ $PROCESSOR =~ xsltproc ]]; then
    # Process stringparam/param values for xsltproc
    if [[ -n "${STRPARMS[@]}" ]]; then
        PARAMETERS=("$(process_params "stringparam" "${STRPARMS[@]}")") || exit_on_error "wrong parameter for function process_params, must be either \"param\" or \"stringparam\""
    fi

    COMMAND="$XSLTPROC $XSLTPROC_ARGS $XINCLUDE ${PARAMETERS[*]} $OUTPUT $STYLESHEET $XMLFILE"

    if [[ -n "$DEBUG" ]]; then
        echo "---------------------------------------------------------"
        echo "Running the following command:"
        echo -e "$COMMAND"
        echo "---------------------------------------------------------"
    fi
    eval "$COMMAND"
    # capture xsltproc return value
    ERR_CODE=$?
else
    run-saxon "$SAXON6_ARGS $OUTPUT $XMLFILE $STYLESHEET" "${PARMS[@]}" "${STRPARMS[@]}"
    # capture saxon6 return value
    ERR_CODE=$?
fi


#-----
# Cleanup
# done via trap, see above

exit $ERR_CODE;