xref: /onnv-gate/usr/src/lib/libshell/common/scripts/xmldocumenttree1.sh (revision 12068:08a39a083754)
18462SApril.Chin@Sun.COM#!/usr/bin/ksh93
28462SApril.Chin@Sun.COM
38462SApril.Chin@Sun.COM#
48462SApril.Chin@Sun.COM# CDDL HEADER START
58462SApril.Chin@Sun.COM#
68462SApril.Chin@Sun.COM# The contents of this file are subject to the terms of the
78462SApril.Chin@Sun.COM# Common Development and Distribution License (the "License").
88462SApril.Chin@Sun.COM# You may not use this file except in compliance with the License.
98462SApril.Chin@Sun.COM#
108462SApril.Chin@Sun.COM# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
118462SApril.Chin@Sun.COM# or http://www.opensolaris.org/os/licensing.
128462SApril.Chin@Sun.COM# See the License for the specific language governing permissions
138462SApril.Chin@Sun.COM# and limitations under the License.
148462SApril.Chin@Sun.COM#
158462SApril.Chin@Sun.COM# When distributing Covered Code, include this CDDL HEADER in each
168462SApril.Chin@Sun.COM# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
178462SApril.Chin@Sun.COM# If applicable, add the following below this CDDL HEADER, with the
188462SApril.Chin@Sun.COM# fields enclosed by brackets "[]" replaced with your own identifying
198462SApril.Chin@Sun.COM# information: Portions Copyright [yyyy] [name of copyright owner]
208462SApril.Chin@Sun.COM#
218462SApril.Chin@Sun.COM# CDDL HEADER END
228462SApril.Chin@Sun.COM#
238462SApril.Chin@Sun.COM
248462SApril.Chin@Sun.COM#
25*12068SRoger.Faulkner@Oracle.COM# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
268462SApril.Chin@Sun.COM#
278462SApril.Chin@Sun.COM
288462SApril.Chin@Sun.COM# Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant
298462SApril.Chin@Sun.COMexport PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin
308462SApril.Chin@Sun.COM
318462SApril.Chin@Sun.COMfunction fatal_error
328462SApril.Chin@Sun.COM{
338462SApril.Chin@Sun.COM	print -u 2 "${progname}: $*"
348462SApril.Chin@Sun.COM	exit 1
358462SApril.Chin@Sun.COM}
368462SApril.Chin@Sun.COM
378462SApril.Chin@Sun.COMfunction attrstrtoattrarray
388462SApril.Chin@Sun.COM{
398462SApril.Chin@Sun.COM#set -o xtrace
408462SApril.Chin@Sun.COM    typeset s="$1"
418462SApril.Chin@Sun.COM    nameref aa=$2 # attribute array
428462SApril.Chin@Sun.COM    integer aa_count=0
438462SApril.Chin@Sun.COM    integer aa_count=0
448462SApril.Chin@Sun.COM    typeset nextattr
458462SApril.Chin@Sun.COM    integer currattrlen=0
468462SApril.Chin@Sun.COM    typeset tagstr
478462SApril.Chin@Sun.COM    typeset tagval
488462SApril.Chin@Sun.COM
498462SApril.Chin@Sun.COM    while (( ${#s} > 0 )) ; do
508462SApril.Chin@Sun.COM        # skip whitespaces
518462SApril.Chin@Sun.COM        while [[ "${s:currattrlen:1}" == ~(E)[[:blank:][:space:]] ]] ; do
528462SApril.Chin@Sun.COM            (( currattrlen++ ))
538462SApril.Chin@Sun.COM        done
548462SApril.Chin@Sun.COM        s="${s:currattrlen:${#s}}"
558462SApril.Chin@Sun.COM
568462SApril.Chin@Sun.COM        # anything left ?
578462SApril.Chin@Sun.COM        (( ${#s} == 0 )) && break
588462SApril.Chin@Sun.COM
598462SApril.Chin@Sun.COM        # Pattern tests:
608462SApril.Chin@Sun.COM        #x="foo=bar huz=123" ; print "${x##~(E)[[:alnum:]_-:]*=[^[:blank:]\"]*}"
618462SApril.Chin@Sun.COM        #x='foo="ba=r o" huz=123' ; print "${x##~(E)[[:alnum:]_-:]*=\"[^\"]*\"}"
628462SApril.Chin@Sun.COM        #x="foo='ba=r o' huz=123" ; print "${x##~(E)[[:alnum:]_-:]*=\'[^\"]*\'}"
638462SApril.Chin@Sun.COM        #x="foox huz=123" ; print "${x##~(E)[[:alnum:]_-:]*}"
648462SApril.Chin@Sun.COM        # All pattern combined via eregex (w|x|y|z):
658462SApril.Chin@Sun.COM        #x='foo="bar=o" huz=123' ; print "${x##~(E)([[:alnum:]_-:]*=[^[:blank:]\"]*|[[:alnum:]_-:]*=\"[^\"]*\"|[[:alnum:]_-:]*=\'[^\"]*\')}"
668462SApril.Chin@Sun.COM        nextattr="${s##~(E)([[:alnum:]_-:]*=[^[:blank:]\"]*|[[:alnum:]_-:]*=\"[^\"]*\"|[[:alnum:]_-:]*=\'[^\"]*\'|[[:alnum:]_-:]*)}"
678462SApril.Chin@Sun.COM        currattrlen=$(( ${#s} - ${#nextattr}))
688462SApril.Chin@Sun.COM
698462SApril.Chin@Sun.COM        # add entry
708462SApril.Chin@Sun.COM        tagstr="${s:0:currattrlen}"
718462SApril.Chin@Sun.COM        if [[ "${tagstr}" == *=* ]] ; then
728462SApril.Chin@Sun.COM            # normal case: attribute with value
738462SApril.Chin@Sun.COM
748462SApril.Chin@Sun.COM            tagval="${tagstr#*=}"
758462SApril.Chin@Sun.COM
768462SApril.Chin@Sun.COM            # strip quotes ('' or "")
778462SApril.Chin@Sun.COM            if [[ "${tagval}" == ~(Elr)(\'.*\'|\".*\") ]] ; then
788462SApril.Chin@Sun.COM                tagval="${tagval:1:${#tagval}-2}"
798462SApril.Chin@Sun.COM            fi
808462SApril.Chin@Sun.COM
818462SApril.Chin@Sun.COM            aa[${aa_count}]=( name="${tagstr%%=*}" value="${tagval}" )
828462SApril.Chin@Sun.COM        else
838462SApril.Chin@Sun.COM            # special case for HTML where you have something like <foo baz>
848462SApril.Chin@Sun.COM            aa[${aa_count}]=( name="${tagstr}" )
858462SApril.Chin@Sun.COM        fi
868462SApril.Chin@Sun.COM        (( aa_count++ ))
878462SApril.Chin@Sun.COM        (( aa_count > 1000 )) && fatal_error "$0: aa_count too large" # assert
888462SApril.Chin@Sun.COM    done
898462SApril.Chin@Sun.COM}
908462SApril.Chin@Sun.COM
918462SApril.Chin@Sun.COM
928462SApril.Chin@Sun.COMfunction handle_document
938462SApril.Chin@Sun.COM{
948462SApril.Chin@Sun.COM#set -o xtrace
958462SApril.Chin@Sun.COM    nameref callbacks=${1}
968462SApril.Chin@Sun.COM    typeset tag_type="${2}"
978462SApril.Chin@Sun.COM    typeset tag_value="${3}"
988462SApril.Chin@Sun.COM    typeset tag_attributes="${4}"
998462SApril.Chin@Sun.COM    nameref doc=${callbacks["arg_tree"]}
1008462SApril.Chin@Sun.COM    nameref nodepath="${stack.items[stack.pos]}"
1018462SApril.Chin@Sun.COM    nameref nodesnum="${stack.items[stack.pos]}num"
1028462SApril.Chin@Sun.COM
1038462SApril.Chin@Sun.COM    case "${tag_type}" in
1048462SApril.Chin@Sun.COM        tag_begin)
1058462SApril.Chin@Sun.COM            nodepath[${nodesnum}]+=(
1068462SApril.Chin@Sun.COM                typeset tagtype="element"
1078462SApril.Chin@Sun.COM                typeset tagname="${tag_value}"
10810898Sroland.mainz@nrubsig.org                compound -A tagattributes
10910898Sroland.mainz@nrubsig.org                compound -A nodes
1108462SApril.Chin@Sun.COM                integer nodesnum=0
1118462SApril.Chin@Sun.COM            )
1128462SApril.Chin@Sun.COM
1138462SApril.Chin@Sun.COM            # fill attributes
1148462SApril.Chin@Sun.COM            if [[ "${tag_attributes}" != "" ]] ; then
1158462SApril.Chin@Sun.COM                attrstrtoattrarray "${tag_attributes}" "nodepath[${nodesnum}].tagattributes"
1168462SApril.Chin@Sun.COM            fi
1178462SApril.Chin@Sun.COM
1188462SApril.Chin@Sun.COM            (( stack.pos++ ))
1198462SApril.Chin@Sun.COM            stack.items[stack.pos]="${stack.items[stack.pos-1]}[${nodesnum}].nodes"
1208462SApril.Chin@Sun.COM            (( nodesnum++ ))
1218462SApril.Chin@Sun.COM            ;;
1228462SApril.Chin@Sun.COM        tag_end)
1238462SApril.Chin@Sun.COM            (( stack.pos-- ))
1248462SApril.Chin@Sun.COM            ;;
1258462SApril.Chin@Sun.COM        tag_text)
1268462SApril.Chin@Sun.COM            nodepath[${nodesnum}]+=(
1278462SApril.Chin@Sun.COM                typeset tagtype="text"
1288462SApril.Chin@Sun.COM                typeset tagvalue="${tag_value}"
1298462SApril.Chin@Sun.COM            )
1308462SApril.Chin@Sun.COM            (( nodesnum++ ))
1318462SApril.Chin@Sun.COM            ;;
1328462SApril.Chin@Sun.COM        tag_comment)
1338462SApril.Chin@Sun.COM            nodepath[${nodesnum}]+=(
1348462SApril.Chin@Sun.COM                typeset tagtype="comment"
1358462SApril.Chin@Sun.COM                typeset tagvalue="${tag_value}"
1368462SApril.Chin@Sun.COM            )
1378462SApril.Chin@Sun.COM            (( nodesnum++ ))
1388462SApril.Chin@Sun.COM            ;;
1398462SApril.Chin@Sun.COM        document_start)
1408462SApril.Chin@Sun.COM            ;;
1418462SApril.Chin@Sun.COM        document_end)
1428462SApril.Chin@Sun.COM            ;;
1438462SApril.Chin@Sun.COM    esac
1448462SApril.Chin@Sun.COM
1458462SApril.Chin@Sun.COM#    print "xmltok: '${tag_type}' = '${tag_value}'"
1468462SApril.Chin@Sun.COM}
1478462SApril.Chin@Sun.COM
1488462SApril.Chin@Sun.COMfunction xml_tok
1498462SApril.Chin@Sun.COM{
1508462SApril.Chin@Sun.COM    typeset buf=""
1518462SApril.Chin@Sun.COM    typeset namebuf=""
1528462SApril.Chin@Sun.COM    typeset attrbuf=""
1538462SApril.Chin@Sun.COM    typeset c=""
1548462SApril.Chin@Sun.COM    typeset isendtag # bool: true/false
1558462SApril.Chin@Sun.COM    typeset issingletag # bool: true/false (used for tags like "<br />")
1568462SApril.Chin@Sun.COM    nameref callbacks=${1}
1578462SApril.Chin@Sun.COM
1588462SApril.Chin@Sun.COM    [[ ! -z "${callbacks["document_start"]}" ]] && ${callbacks["document_start"]} "${1}" "document_start"
1598462SApril.Chin@Sun.COM
1608462SApril.Chin@Sun.COM    while IFS='' read -r -N 1 c ; do
1618462SApril.Chin@Sun.COM        isendtag=false
1628462SApril.Chin@Sun.COM
1638462SApril.Chin@Sun.COM        if [[ "$c" == "<" ]] ; then
1648462SApril.Chin@Sun.COM	    # flush any text content
1658462SApril.Chin@Sun.COM            if [[ "$buf" != "" ]] ; then
1668462SApril.Chin@Sun.COM                [[ ! -z "${callbacks["tag_text"]}" ]] && ${callbacks["tag_text"]} "${1}" "tag_text" "$buf"
1678462SApril.Chin@Sun.COM                buf=""
1688462SApril.Chin@Sun.COM            fi
1698462SApril.Chin@Sun.COM
1708462SApril.Chin@Sun.COM            IFS='' read -r -N 1 c
1718462SApril.Chin@Sun.COM            if [[ "$c" == "/" ]] ; then
1728462SApril.Chin@Sun.COM                isendtag=true
1738462SApril.Chin@Sun.COM            else
1748462SApril.Chin@Sun.COM                buf="$c"
1758462SApril.Chin@Sun.COM            fi
1768462SApril.Chin@Sun.COM            IFS='' read -r -d '>' c
1778462SApril.Chin@Sun.COM            buf+="$c"
1788462SApril.Chin@Sun.COM
1798462SApril.Chin@Sun.COM	    # handle comments
1808462SApril.Chin@Sun.COM	    if [[ "$buf" == ~(El)!-- ]] ; then
1818462SApril.Chin@Sun.COM	        # did we read the comment completely ?
1828462SApril.Chin@Sun.COM	        if [[ "$buf" != ~(Elr)!--.*-- ]] ; then
1838462SApril.Chin@Sun.COM		    buf+=">"
1848462SApril.Chin@Sun.COM	            while [[ "$buf" != ~(Elr)!--.*-- ]] ; do
1858462SApril.Chin@Sun.COM		        IFS='' read -r -N 1 c || break
1868462SApril.Chin@Sun.COM		        buf+="$c"
1878462SApril.Chin@Sun.COM		    done
1888462SApril.Chin@Sun.COM		fi
1898462SApril.Chin@Sun.COM
1908462SApril.Chin@Sun.COM		[[ ! -z "${callbacks["tag_comment"]}" ]] && ${callbacks["tag_comment"]} "${1}" "tag_comment" "${buf:3:${#buf}-5}"
1918462SApril.Chin@Sun.COM		buf=""
1928462SApril.Chin@Sun.COM		continue
1938462SApril.Chin@Sun.COM	    fi
1948462SApril.Chin@Sun.COM
1958462SApril.Chin@Sun.COM	    # check if the tag starts and ends at the same time (like "<br />")
1968462SApril.Chin@Sun.COM	    if [[ "${buf}" == ~(Er).*/ ]] ; then
1978462SApril.Chin@Sun.COM	        issingletag=true
1988462SApril.Chin@Sun.COM		buf="${buf%*/}"
1998462SApril.Chin@Sun.COM	    else
2008462SApril.Chin@Sun.COM	        issingletag=false
2018462SApril.Chin@Sun.COM	    fi
2028462SApril.Chin@Sun.COM
2038462SApril.Chin@Sun.COM	    # check if the tag has attributes (e.g. space after name)
2048462SApril.Chin@Sun.COM	    if [[ "$buf" == ~(E)[[:space:][:blank:]] ]] ; then
2058462SApril.Chin@Sun.COM	        namebuf="${buf%%~(E)[[:space:][:blank:]].*}"
2068462SApril.Chin@Sun.COM                attrbuf="${buf#~(E).*[[:space:][:blank:]]}"
2078462SApril.Chin@Sun.COM            else
2088462SApril.Chin@Sun.COM	        namebuf="$buf"
2098462SApril.Chin@Sun.COM		attrbuf=""
2108462SApril.Chin@Sun.COM	    fi
2118462SApril.Chin@Sun.COM
2128462SApril.Chin@Sun.COM            if ${isendtag} ; then
2138462SApril.Chin@Sun.COM                [[ ! -z "${callbacks["tag_end"]}" ]] && ${callbacks["tag_end"]} "${1}" "tag_end" "$namebuf"
2148462SApril.Chin@Sun.COM            else
2158462SApril.Chin@Sun.COM                [[ ! -z "${callbacks["tag_begin"]}" ]] && ${callbacks["tag_begin"]} "${1}" "tag_begin" "$namebuf" "$attrbuf"
2168462SApril.Chin@Sun.COM
2178462SApril.Chin@Sun.COM                # handle tags like <br/> (which are start- and end-tag in one piece)
2188462SApril.Chin@Sun.COM                if ${issingletag} ; then
2198462SApril.Chin@Sun.COM                    [[ ! -z "${callbacks["tag_end"]}" ]] && ${callbacks["tag_end"]} "${1}" "tag_end" "$namebuf"
2208462SApril.Chin@Sun.COM                fi
2218462SApril.Chin@Sun.COM            fi
2228462SApril.Chin@Sun.COM            buf=""
2238462SApril.Chin@Sun.COM        else
2248462SApril.Chin@Sun.COM            buf+="$c"
2258462SApril.Chin@Sun.COM        fi
2268462SApril.Chin@Sun.COM    done
2278462SApril.Chin@Sun.COM
2288462SApril.Chin@Sun.COM    [[ ! -z "${callbacks["document_end"]}" ]] && ${callbacks["document_end"]} "${1}" "document_end" "exit_success"
2298462SApril.Chin@Sun.COM
2308462SApril.Chin@Sun.COM    print # final newline to make filters like "sed" happy
2318462SApril.Chin@Sun.COM}
2328462SApril.Chin@Sun.COM
2338462SApril.Chin@Sun.COMfunction print_sample1_xml
2348462SApril.Chin@Sun.COM{
2358462SApril.Chin@Sun.COMcat <<EOF
2368462SApril.Chin@Sun.COM<br />
2378462SApril.Chin@Sun.COM<score-partwise instrument="flute1">
2388462SApril.Chin@Sun.COM        <identification>
2398462SApril.Chin@Sun.COM            <kaiman>nocrocodile</kaiman>
2408462SApril.Chin@Sun.COM        </identification>
2418462SApril.Chin@Sun.COM        <!-- a comment -->
2428462SApril.Chin@Sun.COM        <partlist>
2438462SApril.Chin@Sun.COM            <foo>myfootext</foo>
2448462SApril.Chin@Sun.COM            <bar>mybartext</bar>
2458462SApril.Chin@Sun.COM            <snap />
2468462SApril.Chin@Sun.COM            <!-- another
2478462SApril.Chin@Sun.COM                 comment -->
2488462SApril.Chin@Sun.COM            <ttt>myttttext</ttt>
2498462SApril.Chin@Sun.COM        </partlist>
2508462SApril.Chin@Sun.COM</score-partwise>
2518462SApril.Chin@Sun.COMEOF
2528462SApril.Chin@Sun.COM}
2538462SApril.Chin@Sun.COM
2548462SApril.Chin@Sun.COMfunction usage
2558462SApril.Chin@Sun.COM{
2568462SApril.Chin@Sun.COM    OPTIND=0
2578462SApril.Chin@Sun.COM    getopts -a "${progname}" "${xmldocumenttree1_usage}" OPT '-?'
2588462SApril.Chin@Sun.COM    exit 2
2598462SApril.Chin@Sun.COM}
2608462SApril.Chin@Sun.COM
2618462SApril.Chin@Sun.COM# program start
2628462SApril.Chin@Sun.COMbuiltin basename
2638462SApril.Chin@Sun.COMbuiltin cat
2648462SApril.Chin@Sun.COMbuiltin date
2658462SApril.Chin@Sun.COMbuiltin uname
2668462SApril.Chin@Sun.COM
2678462SApril.Chin@Sun.COMtypeset progname="${ basename "${0}" ; }"
2688462SApril.Chin@Sun.COM
2698462SApril.Chin@Sun.COMtypeset -r xmldocumenttree1_usage=$'+
27010898Sroland.mainz@nrubsig.org[-?\n@(#)\$Id: xmldocumenttree1 (Roland Mainz) 2009-05-09 \$\n]
2718462SApril.Chin@Sun.COM[-author?Roland Mainz <roland.mainz@nrubsig.org>]
2728462SApril.Chin@Sun.COM[+NAME?xmldocumenttree1 - XML tree demo]
2738462SApril.Chin@Sun.COM[+DESCRIPTION?\bxmldocumenttree\b is a small ksh93 compound variable demo
2748462SApril.Chin@Sun.COM        which reads a XML input file, converts it into an internal
2758462SApril.Chin@Sun.COM        variable tree representation and outputs it in the format
27610898Sroland.mainz@nrubsig.org        specified by viewmode (either "list", "namelist", "tree" or "compacttree").]
2778462SApril.Chin@Sun.COM
2788462SApril.Chin@Sun.COMfile viewmode
2798462SApril.Chin@Sun.COM
2808462SApril.Chin@Sun.COM[+SEE ALSO?\bksh93\b(1)]
2818462SApril.Chin@Sun.COM'
2828462SApril.Chin@Sun.COM
2838462SApril.Chin@Sun.COMwhile getopts -a "${progname}" "${xmldocumenttree1_usage}" OPT ; do
2848462SApril.Chin@Sun.COM#    printmsg "## OPT=|${OPT}|, OPTARG=|${OPTARG}|"
2858462SApril.Chin@Sun.COM    case ${OPT} in
2868462SApril.Chin@Sun.COM        *)    usage ;;
2878462SApril.Chin@Sun.COM    esac
2888462SApril.Chin@Sun.COMdone
2898462SApril.Chin@Sun.COMshift $((OPTIND-1))
2908462SApril.Chin@Sun.COM
2918462SApril.Chin@Sun.COMtypeset xmlfile="$1"
2928462SApril.Chin@Sun.COMtypeset viewmode="$2"
2938462SApril.Chin@Sun.COM
2948462SApril.Chin@Sun.COMif [[ "${xmlfile}" == "" ]] ; then
2958462SApril.Chin@Sun.COM    fatal_error $"No file given."
2968462SApril.Chin@Sun.COMfi
2978462SApril.Chin@Sun.COM
29810898Sroland.mainz@nrubsig.orgif [[ "${viewmode}" != ~(Elr)(list|namelist|tree|compacttree) ]] ; then
2998462SApril.Chin@Sun.COM    fatal_error $"Invalid view mode \"${viewmode}\"."
3008462SApril.Chin@Sun.COMfi
3018462SApril.Chin@Sun.COM
30210898Sroland.mainz@nrubsig.orgcompound xdoc
30310898Sroland.mainz@nrubsig.orgcompound -A xdoc.nodes
3048462SApril.Chin@Sun.COMinteger xdoc.nodesnum=0
3058462SApril.Chin@Sun.COM
30610898Sroland.mainz@nrubsig.orgcompound stack
3078462SApril.Chin@Sun.COMtypeset -a stack.items=( [0]="doc.nodes" )
3088462SApril.Chin@Sun.COMinteger stack.pos=0
3098462SApril.Chin@Sun.COM
3108462SApril.Chin@Sun.COM# setup callbacks for xml_tok
3118462SApril.Chin@Sun.COMtypeset -A document_cb # callbacks for xml_tok
3128462SApril.Chin@Sun.COMdocument_cb["document_start"]="handle_document"
3138462SApril.Chin@Sun.COMdocument_cb["document_end"]="handle_document"
3148462SApril.Chin@Sun.COMdocument_cb["tag_begin"]="handle_document"
3158462SApril.Chin@Sun.COMdocument_cb["tag_end"]="handle_document"
3168462SApril.Chin@Sun.COMdocument_cb["tag_text"]="handle_document"
3178462SApril.Chin@Sun.COMdocument_cb["tag_comment"]="handle_document"
3188462SApril.Chin@Sun.COM# argument for "handle_document"
3198462SApril.Chin@Sun.COMdocument_cb["arg_tree"]="xdoc"
3208462SApril.Chin@Sun.COM
3218462SApril.Chin@Sun.COM
3228462SApril.Chin@Sun.COMif [[ "${xmlfile}" == "#sample1" ]] ; then
3238462SApril.Chin@Sun.COM    print_sample1_xml | xml_tok document_cb
3248462SApril.Chin@Sun.COMelif [[ "${xmlfile}" == "#sample2" ]] ; then
3258462SApril.Chin@Sun.COM    /usr/sfw/bin/wget \
3268462SApril.Chin@Sun.COM            --user-agent='ksh93_xmldocumenttree' \
3278462SApril.Chin@Sun.COM	    --output-document=- \
3288462SApril.Chin@Sun.COM	    'http://www.google.com/custom?q=gummi+bears' |
3298462SApril.Chin@Sun.COM        /usr/bin/iconv -f "ISO8859-1" |
3308462SApril.Chin@Sun.COM        xml_tok document_cb
3318462SApril.Chin@Sun.COMelse
3328462SApril.Chin@Sun.COM    cat "${xmlfile}" | xml_tok document_cb
3338462SApril.Chin@Sun.COMfi
3348462SApril.Chin@Sun.COM
3358462SApril.Chin@Sun.COMprint -u2 "#parsing completed."
3368462SApril.Chin@Sun.COM
3378462SApril.Chin@Sun.COMcase "${viewmode}" in
3388462SApril.Chin@Sun.COM    list)
3398462SApril.Chin@Sun.COM        set | egrep "xdoc.*(tagname|tagtype|tagval|tagattributes)" | fgrep -v ']=$'
3408462SApril.Chin@Sun.COM        ;;
3418462SApril.Chin@Sun.COM    namelist)
3428462SApril.Chin@Sun.COM        typeset + | egrep "xdoc.*(tagname|tagtype|tagval|tagattributes)"
3438462SApril.Chin@Sun.COM        ;;
3448462SApril.Chin@Sun.COM    tree)
34510898Sroland.mainz@nrubsig.org        print -v xdoc
34610898Sroland.mainz@nrubsig.org        ;;
34710898Sroland.mainz@nrubsig.org    compacttree)
34810898Sroland.mainz@nrubsig.org        print -C xdoc
3498462SApril.Chin@Sun.COM        ;;
3508462SApril.Chin@Sun.COM       *)
3518462SApril.Chin@Sun.COM        fatal_error $"Invalid view mode \"${viewmode}\"."
3528462SApril.Chin@Sun.COM        ;;
3538462SApril.Chin@Sun.COMesac
3548462SApril.Chin@Sun.COM
3558462SApril.Chin@Sun.COMprint -u2 "#done."
3568462SApril.Chin@Sun.COM
3578462SApril.Chin@Sun.COMexit 0
3588462SApril.Chin@Sun.COM# EOF.
359