[Previous] [Contents] [Next]


Prefixing an Element


In Listing 19.5, you already saw how you can use "(sosofo-append (literal ""))" to put a text string in front of an element's content. Wouldn't it be nice if you could let the name of the element determine the prefix that gets put in front of the element? Warnings could then be prefixed with the text "Warning" and so on. Have a look at the XML code in Listing 19.8.

Listing 19.8 XML Cookbook File 1, Prefixing an Element with its Name
1:  <?xml version="1.0">
2:  <!DOCTYPE DOC [
3:  <!ELEMENT DOC     (TITLE | CAUTION | NOTE | PARA)*>
4:  <!ELEMENT TITLE   (#PCDATA)>
5:  <!ELEMENT NOTE    (#PCDATA)>
6:  <!ELEMENT PARA    (#PCDATA)>
7:  <!ELEMENT CAUTION (#PCDATA)>
8:  ]>
9:  <DOC>
10: <TITLE>Simple XML to HTML Conversion</TITLE>
11: <PARA>This sample document demonstrates how you can
12: convert the tag name into a piece of text inside an
13: element.</PARA>
14: <NOTE>This is a note.</NOTE>
15: <PARA>This second paragraph proves that normal text is still
16: untouched.</PARA>
17: <CAUTION>This is a caution.</CAUTION>
18: </DOC>

Listing 19.9 is the DSSSL style sheet that goes with Listing 19.7:

Listing 19.9 DSSSL Cookbook File 1, Prefixing an Element with Text
1:  <!DOCTYPE style-sheet PUBLIC
2:      "-//James Clark//DTD DSSSL Style Sheet//EN"[
3:  <!ENTITY lt "&#38;#60;">
4:  <!ENTITY gt "&#62;">
5:  ]>
6:  (declare-flow-object-class element
7:    "UNREGISTERED::James Clark//Flow Object Class::element")
8:  (declare-flow-object-class document-type
9:    "UNREGISTERED::James Clark//Flow Object Class::document-type")
10:  (declare-flow-object-class empty-element
11:   "UNREGISTERED::James Clark//Flow Object Class::empty-element")
12: (declare-flow-object-class formatting-instruction
13:   "UNREGISTERED::James Clark//Flow Object
14:     Class::formatting-instruction")
15:
16: (define debug
17: (external-procedure "UNREGISTERED::James Clark//Procedure::debug"))
18:
19: (define (make-special-para)
20:   (make sequence
21:     (make element
22:       gi: "P"
23:     (make element
24:       gi: "B"
25:       (literal (string-append (gi) ":"))))
26:     (make element
27:       gi: "BLOCKQUOTE"
28:       (process-children))))
29:
30: (element DOC
31:   (sosofo-append
32:     (make document-type
33:       name:  "HTML"
34:       public-id: "-//W3C//DTD HTML 3.2//EN")
35:         (make element
36:           gi:  "HTML"
37:             (sosofo-append
38:               (make element
39:                 gi:  "HEAD"
40:                   (make element
41:                     gi:  "TITLE"
42:                       (sosofo-append
43:                          (literal "Simple XML-to-HTML Conversion"))))
44:               (make element gi:  "BODY"
45:                (process-children))))))
46:
47: (element TITLE (make element gi: "H1" ))
48:
49: (element NOTE (make-special-para))
50: (element CAUTION (make-special-para))
51:
52: (element PARA (make element gi: "P" ))

Ignore the DOC, TITLE, and P elements. The DOC element is messy, but fairly straightforward if you follow the logic step by step; all it does is output the correct HTML code when it sees the DOC element. The TITLE and P elements are just straight mappings.

It is the NOTE and CAUTION elements that are interesting. Because I want them both to be treated as special, I've defined a procedure make-special-para. Taking away the indentation (this helps me to keep track of all the opening and closing brackets), this procedure looks like this:

(define (make-special-para)
  (make sequence (make element gi: "P" (make element gi: "B"
      (literal (string-append (gi) ":"))))
    (make element gi: "BLOCKQUOTE" (process-children))))

What I do is create a sequence (make sequence). This sequence consists of an element (P), so it's going to wrap what follows in a P element. What follows is a literal composed of the name of the element (gi) with a colon (:) appended to it (hence, string-append). This is also followed by a make element instruction, this time to make a BLOCKQUOTE element and then, finally, the contents of the element (process-children).

Let's have a look at the HTML code this produces-Listing 19.9.

Listing 19.10 HTML Cookbook File 1, Prefixed Element Output
1:  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
2:  <HTML>
3:  <HEAD>
4:  <TITLE>Simple XML-to-HTML Conversion</TITLE>
5:  </HEAD>
6:  <BODY>
7:  <H1>Simple XML to HTML Conversion</H1>
8:  <P>This sample document demonstrates how you can
9:  convert the tag name into a piece of text inside an
10: element.</P>
11: <P><B>NOTE:</B></P>
12: <BLOCKQUOTE>This is a note.</BLOCKQUOTE>
13: <P>This second paragraph proves that normal text is still
14: untouched.</P>
15: <P><B>CAUTION:</B></P>
16: <BLOCKQUOTE>This is a caution.</BLOCKQUOTE>
17: </BODY>
18: </HTML>

And Figure 19.7 shows what the HTML file looks like in a Web browser.
Figure 19.7 The prefixed element in the displayed HTML.

[Previous] [Contents] [Next]