Question

I have a list of pair, like this:

((IDENTIFRIAR . str) (SYMBOL . =) (STRING-CONSTANT .  Hello world! ) (BOOLEAN-CONSTANT . true))

And I want to generate and output it as xml, like:

<elements>
    <IDENTIFRIAR>str<IDENTIFRIAR/>
    <SYMBOL>=<SYMBOL/>
    <STRING-CONSTANT> Hello world!<STRING-CONSTANT/>
    <BOOLEAN-CONSTANT>true<BOOLEAN-CONSTANT/>
<elements/>

How can I do it? I found myself looking at some long documentation of XML and xexpr and not understanding anything about how I can actually create, append and change XML entities.

Was it helpful?

Solution

First, let's clean up your input. You had e.g.:

'(STRING-CONSTANT . Hello world!)

which is invalid.

Instead let's make an association list where the values are strings, and use that as the input:

(define alist '((IDENTIFRIAR . "str")
                (SYMBOL . "=")
                (STRING-CONSTANT . "Hello world!" )
                (BOOLEAN-CONSTANT . "true")))

Let's transform that to an x-expr, which is a way of representing XML as an s-expression.

(define xexprs (for/list ([a (in-list alist)])
                 (match-define (cons k v) a)
                 `(,k () ,v)))
;; =>
;; '((IDENTIFRIAR () "str")
;;   (SYMBOL () "=")
;;   (STRING-CONSTANT () "Hello world!")
;;   (BOOLEAN-CONSTANT () "true"))

Now let's convert that using xexpr->string from Racket's xml collection.

(require xml)
(xexpr->string `(elements () ,@xexprs))
;; =>
;; "<elements><IDENTIFRIAR>str</IDENTIFRIAR><SYMBOL>=</SYMBOL><STRING-CONSTANT>Hello world!</STRING-CONSTANT><BOOLEAN-CONSTANT>true</BOOLEAN-CONSTANT></elements>"

If you want indenting, then instead:

(display-xml/content (xexpr->xml `(elements () ,@xexprs)))

which displays:

<elements>
  <IDENTIFRIAR>
    str
  </IDENTIFRIAR>
  <SYMBOL>
    =
  </SYMBOL>
  <STRING-CONSTANT>
    Hello world!
  </STRING-CONSTANT>
  <BOOLEAN-CONSTANT>
    true
  </BOOLEAN-CONSTANT>
</elements>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top