XQuery/Web XML Viewer

From Wikibooks, open books for an open world
Jump to: navigation, search

Motivation[edit]

You want to view XML documents using your web browser using HTML markup.

Method[edit]

We will use an XQuery function that uses the dispatch pattern and the typeswitch function.

Sample Input[edit]

<aaa a1="A1" a2="A2" a3="A3">
    <bbb b1="B1" b2="B2" b3="B3">BBB</bbb>
    <ccc c1="C1" c2="C2" c3="C3">
       <ddd d1="D1" d2="D2" d3="D3">DDD</ddd>
       <eee>
           <fff>FFF</fff>
       </eee>
    </ccc>
</aaa>

Sample XML to HMTL Function[edit]

(: sequence dispatcher :)
declare function xml-to-html:dispatch($input as node()*, $depth as xs:integer) as item()* {
let $left-margin := concat('margin-left: ', ($depth * 5), 'px' )
for $node in $input
   return 
      typeswitch($node)
        case text() return normalize-space(<span class="d">{$node}</span>)
        case element()
           return
              <div class="element" style="{$left-margin}">
                    <span class="t">&lt;{name($node)}</span>
                    { (: for each attribute create two spans for the name and value :)
                     for $att in $node/@*
                        return
                           (
                              <span class="an"> {name($att)}=</span>,
                              <span class="av">"{string($att)}"</span>
                           )
                    }
                    {normalize-space(<span class="t">&gt;</span>)}
                    { (: now get the sub elements :)
                       for $c in $node
                          return xml-to-html:dispatch($c/node(), $depth + 1)
                    }
                    <span class="t">&lt;/{name($node)}&gt;</span>
             </div> 
        (: otherwise pass it through.  Used for comments, and PIs :)
        default return $node
};

Sample Driver[edit]

xquery version "1.0";
 
import module namespace xml-to-html="http://example.com/xml-to-html" at "xml-to-html.xqm";
 
let $title := 'View XML as HTML'
 
let $input :=
<aaa a1="A1" a2="A2" a3="A3">
    <bbb b1="B1" b2="B2" b3="B3">BBB</bbb>
    <ccc c1="C1" c2="C2" c3="C3">
       <ddd d1="D1" d2="D2" d3="D3">DDD</ddd>
       <eee>
           <fff>FFF</fff>
       </eee>
    </ccc>
</aaa>
 
let $output := xml-to-html:xml-to-html($input, 1)
 
return
<html>
   <head>
      <title>{$title}</title>
      <link type="text/css" rel="stylesheet" href="syntax-colors-oxygen.css"/>
   </head>
   <body>
      <div class="xml">
        {$output}
      </div>
   </body>
</html>

Sample Output[edit]

<div class="xml">
    <div class="element" style="margin-left: 5px">
        <span class="t">&lt;aaa</span>
        <span class="an">a1=</span>
        <span class="av">"A1"</span>
        <span class="an">a2=</span>
        <span class="av">"A2"</span>
        <span class="an">a3=</span>
        <span class="av">"A3"</span>&gt;<div class="element" style="margin-left: 10px">
            <span class="t">&lt;bbb</span>
            <span class="an">b1=</span>
            <span class="av">"B1"</span>
            <span class="an">b2=</span>
            <span class="av">"B2"</span>
            <span class="an">b3=</span>
            <span class="av">"B3"</span>&gt;BBB<span class="t">&lt;/bbb&gt;</span>
        </div>
        <div class="element" style="margin-left: 10px">
            <span class="t">&lt;ccc</span>
            <span class="an">c1=</span>
            <span class="av">"C1"</span>
            <span class="an">c2=</span>
            <span class="av">"C2"</span>
            <span class="an">c3=</span>
            <span class="av">"C3"</span>&gt;<div class="element" style="margin-left: 15px">
                <span class="t">&lt;ddd</span>
                <span class="an">d1=</span>
                <span class="av">"D1"</span>
                <span class="an">d2=</span>
                <span class="av">"D2"</span>
                <span class="an">d3=</span>
                <span class="av">"D3"</span>&gt;DDD<span class="t">&lt;/ddd&gt;</span>
            </div>
            <div class="element" style="margin-left: 15px">
                <span class="t">&lt;eee</span>&gt;<div class="element" style="margin-left: 20px">
                    <span class="t">&lt;fff</span>&gt;FFF<span class="t">&lt;/fff&gt;</span>
                </div>
                <span class="t">&lt;/eee&gt;</span>
            </div>
            <span class="t">&lt;/ccc&gt;</span>
        </div>
        <span class="t">&lt;/aaa&gt;</span>
    </div>
</div>

Sample CSS File[edit]

File: syntax-colors-oxygen.css

/* Begin and end tag Delimiter */
.t {color: blue;}
/* Attribute Name and equal sign */
.an {color: orange;}
/* Attribute Values and equal sign */
.av {color: orange;}
/* Element Data Content */
.d {color: black;}

Screen Image[edit]

screen image of rendering in browser with CSS file