XML/Output

From Rosetta Code
Task
XML/Output
You are encouraged to solve this task according to the task description, using any language you may know.

Create a function that takes a list of character names and a list of corresponding remarks and returns an XML document of <Character> elements each with a name attributes and each enclosing its remarks. All <Character> elements are to be enclosed in turn, in an outer <CharacterRemarks> element.

As an example, calling the function with the three names of:

April
Tam O'Shanter
Emily

And three remarks of:

Bubbly: I'm > Tam and <= Emily
Burns: "When chapman billies leave the street ..."
Short & shrift

Should produce the XML (but not necessarily with the indentation): <lang xml><CharacterRemarks>

   <Character name="April">Bubbly: I'm > Tam and <= Emily</Character>
   <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character>
   <Character name="Emily">Short & shrift</Character>

</CharacterRemarks></lang>

The document may include an <?xml?> declaration and document type declaration, but these are optional. If attempting this task by direct string manipulation, the implementation must include code to perform entity substitution for the characters that have entities defined in the XML 1.0 specification.

Note: the example is chosen to show correct escaping of XML strings. Note too that although the task is written to take two lists of corresponding data, a single mapping/hash/dictionary of names to remarks is also acceptable.

Note to editors: Program output with escaped characters will be viewed as the character on the page so you need to 'escape-the-escapes' to make the RC entry display what would be shown in a plain text viewer (See this). Alternately, output can be placed in <lang xml></lang> tags without any special treatment.

Ada

Works with: GNAT

Uses XML/Ada from AdaCore.

character_remarks.adb: <lang Ada>with Ada.Strings.Unbounded; with Ada.Text_IO.Text_Streams; with DOM.Core.Documents; with DOM.Core.Elements; with DOM.Core.Nodes;

procedure Character_Remarks is

  package DC renames DOM.Core;
  package IO renames Ada.Text_IO;
  package US renames Ada.Strings.Unbounded;
  type Remarks is record
     Name : US.Unbounded_String;
     Text : US.Unbounded_String;
  end record;
  type Remark_List is array (Positive range <>) of Remarks;
  My_Remarks : Remark_List :=
     ((US.To_Unbounded_String ("April"),
       US.To_Unbounded_String ("Bubbly: I'm > Tam and <= Emily")),
      (US.To_Unbounded_String ("Tam O'Shanter"),
       US.To_Unbounded_String ("Burns: ""When chapman billies leave the street ...""")),
      (US.To_Unbounded_String ("Emily"),
       US.To_Unbounded_String ("Short & shrift")));
  My_Implementation : DC.DOM_Implementation;
  My_Document       : DC.Document := DC.Create_Document (My_Implementation);
  My_Root_Node      : DC.Element  := DC.Nodes.Append_Child (My_Document,
                                        DC.Documents.Create_Element (My_Document, "CharacterRemarks"));
  My_Element_Node   : DC.Element;
  My_Text_Node      : DC.Text;

begin

  for I in My_Remarks'Range loop
     My_Element_Node := DC.Nodes.Append_Child (My_Root_Node,
                           DC.Documents.Create_Element (My_Document, "Character"));
     DC.Elements.Set_Attribute (My_Element_Node, "Name", US.To_String (My_Remarks (I).Name));
     My_Text_Node    := DC.Nodes.Append_Child (My_Element_Node,
                           DC.Documents.Create_Text_Node (My_Document, US.To_String (My_Remarks (I).Text)));
  end loop;
  DC.Nodes.Write (IO.Text_Streams.Stream (IO.Standard_Output),
                  N => My_Document,
                  Pretty_Print => True);

end Character_Remarks;</lang>

AutoHotkey

<lang AutoHotkey>gosub constants names := xmlescape(names) remarks := xmlescape(remarks)

stringsplit, remarks, remarks, `n xml = "<CharacterRemarks>"

loop, parse, names, `n

 xml .= "<Character name=" . A_LoopField . ">" . remarks%A_Index%
 . "</Character>`n"

xml .= "</CharacterRemarks>"

msgbox % xml return

xmlescape(string) {

 static
 punc = ",>,<,<=,>=,',&  ; "
 xmlpunc = ",>,<,<=,>=,',&
 if !punc1
 {

StringSplit, punc, punc, `, StringSplit, xmlpunc, xmlpunc, `,

 }
 escaped := string
 loop, parse, punc, `,
 {
 StringReplace, escaped, escaped, % A_LoopField, % xmlpunc%A_Index%, All
 }
 Return escaped

}

constants:

  1. LTrim

names = (

 April
 Tam O'Shanter
 Emily

)

remarks = (

 Bubbly: I'm > Tam and <= Emily
 Burns: "When chapman billies leave the street ..."
 Short & shrift

) return</lang>

BASIC

Works with: FreeBASIC

<lang basic>Data "April", "Bubbly: I'm > Tam and <= Emily", _

   "Tam O'Shanter", "Burns: ""When chapman billies leave the street ...""", _
   "Emily", "Short & shrift"

Declare Function xmlquote(ByRef s As String) As String Dim n As Integer, dev As String, remark As String

Print "<CharacterRemarks>" For n = 0 to 2

   Read dev, remark
   Print "  <Character name="""; xmlquote(dev); """>"; _
       xmlquote(remark); "</Character>"

Next Print "</CharacterRemarks>"

End

Function xmlquote(ByRef s As String) As String

   Dim n As Integer
   Dim r As String
   For n = 0 To Len(s)
       Dim c As String
       c = Mid(s,n,1)
       Select Case As Const Asc(c)
       Case Asc("<")
            r = r + "<"
       Case Asc(">")
            r = r + ">"
       Case Asc("&")
            r = r + "&"
       Case Asc("""")
            r = r + """
       Case Asc("'")
            r = r + "'"
       Case Else
            r = r + c
       End Select
   Next
   Function = r

End Function</lang>

C

Library: libXML

<lang c>#include <stdio.h>

  1. include <stdlib.h>
  2. include <string.h>
  3. include <libxml/parser.h>
  4. include <libxml/tree.h>

const char *names[] = {

 "April", "Tam O'Shanter", "Emily", NULL

}; const char *remarks[] = {

 "Bubbly: I'm > Tam and <= Emily",
 "Burns: \"When chapman billies leave the street ...\"",
 "Short & shrift", NULL

};

int main() {

 xmlDoc *doc = NULL;
 xmlNode *root = NULL, *node;
 const char **next;
 int a;
 doc = xmlNewDoc("1.0");
 root = xmlNewNode(NULL, "CharacterRemarks");
 xmlDocSetRootElement(doc, root);
 for(next = names, a = 0; *next != NULL; next++, a++) {
   node = xmlNewNode(NULL, "Character");
   (void)xmlNewProp(node, "name", *next);
   xmlAddChild(node, xmlNewText(remarks[a]));
   xmlAddChild(root, node);
 }
 xmlElemDump(stdout, doc, root);
 xmlFreeDoc(doc);
 xmlCleanupParser();
 
 return EXIT_SUCCESS;

}</lang>

C++

Library: Boost <lang cpp>#include <vector>

  1. include <utility>
  2. include <iostream>
  3. include <boost/algorithm/string.hpp>

std::string create_xml( std::vector<std::string> & ,std::vector<std::string> & ) ;

int main( ) {

  std::vector<std::string> names , remarks ;
  names.push_back( "April" ) ;
  names.push_back( "Tam O'Shantor" ) ;
  names.push_back ( "Emily" ) ;
  remarks.push_back( "Bubbly, I'm > Tam and <= Emily" ) ;
  remarks.push_back( "Burns: \"When chapman billies leave the street ...\"" ) ;
  remarks.push_back( "Short & shrift" ) ;
  std::cout << "This is in XML:\n" ;
  std::cout << create_xml( names , remarks ) << std::endl ;
  return 0 ;

}

std::string create_xml( std::vector<std::string> & names ,

     std::vector<std::string> & remarks ) {
  std::vector<std::pair<std::string , std::string> > entities ;
  entities.push_back( std::make_pair( "&" , "&" ) ) ;
  entities.push_back( std::make_pair( "<" , "<" ) ) ;
  entities.push_back( std::make_pair( ">" , ">" ) ) ;
  std::string xmlstring ( "<CharacterRemarks>\n" ) ;
  std::vector<std::string>::iterator vsi = names.begin( ) ;
  typedef std::vector<std::pair<std::string , std::string> >::iterator Vpss ;
  for ( ; vsi != names.end( ) ; vsi++ ) {
     for ( Vpss vs = entities.begin( ) ; vs != entities.end( ) ; vs++ ) {

boost::replace_all ( *vsi , vs->first , vs->second ) ;

     }
  }
  for ( vsi = remarks.begin( ) ; vsi != remarks.end( ) ; vsi++ ) {
     for ( Vpss vs = entities.begin( ) ; vs != entities.end( ) ; vs++ ) {

boost::replace_all ( *vsi , vs->first , vs->second ) ;

     }
  }
  for ( int i = 0 ; i < names.size( ) ; i++ ) {
     xmlstring.append( "\t<Character name=\"").append( names[ i ] ).append( "\">")

.append( remarks[ i ] ).append( "</Character>\n" ) ;

  }
  xmlstring.append( "</CharacterRemarks>" ) ;
  return xmlstring ;

}</lang>

C#

Works with: C# version 3.0+

<lang csharp>using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq;

class Program {

   static string CreateXML(Dictionary<string, string> characterRemarks)
   {
       var remarks = characterRemarks.Select(r => new XElement("Character", r.Value, new XAttribute("Name", r.Key)));
       var xml = new XElement("CharacterRemarks", remarks);
       return xml.ToString();
   }
   static void Main(string[] args)
   {
       var characterRemarks = new Dictionary<string, string>
       {
           { "April", "Bubbly: I'm > Tam and <= Emily" },
           { "Tam O'Shanter", "Burns: \"When chapman billies leave the street ...\"" },
           { "Emily", "Short & shrift" }
       };
       string xml = CreateXML(characterRemarks);
       Console.WriteLine(xml);
   }

}</lang>

Clojure

<lang lisp>(use 'clojure.xml) (defn character-remarks-xml [characters remarks]

 (with-out-str (emit-element
                 {:tag :CharacterRemarks,
                  :attrs nil,
                  :content (vec (for [item (map vector characters remarks)]
                                  {:tag :Character,
                                   :attrs {:name (item 0)},
                                   :content [(item 1)]}) )})))</lang>

Common Lisp

Library: Closure XML

<lang lisp>(defun write-xml (characters lines &optional (out *standard-output*))

 (let* ((doc (dom:create-document 'rune-dom:implementation nil nil nil))
        (chars (dom:append-child doc (dom:create-element doc "Characters"))))
   (map nil (lambda (character line)
              (let ((c (dom:create-element doc "Character")))
                (dom:set-attribute c "name" character)
                (dom:append-child c (dom:create-text-node doc line))
                (dom:append-child chars c)))
        characters lines)
   (write-string (dom:map-document (cxml:make-rod-sink) doc) out)))</lang>

Example of use:

<lang lisp>(write-xml '("April" "Tam O'Shanter" "Emily")

          '("Bubbly: I'm > Tam and <= Emily"
            "Burns: \"When chapman billies leave the street ...\""
            "Short & shrift"))</lang>

output:

<?xml version="1.0" encoding="UTF-8"?>
<Characters><Character name="April">Bubbly: I'm &gt; Tam and &lt;= Emily</Character><Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character><Character name="Emily">Short &amp; shrift</Character></Characters>

D

Library: KXML

<lang d>import kxml.xml; char[][][]characters =

       [["April","Bubbly: I'm > Tam and <= Emily"],
       ["Tam O'Shanter","Burns: \"When chapman billies leave the street ...\""],
       ["Emily","Short & shrift"]];

void addChars(XmlNode root,char[][][]info) {

       auto remarks = new XmlNode("CharacterRemarks");
       root.addChild(remarks);
       foreach(set;info) {
               remarks.addChild((new XmlNode("Character")).setAttribute("name",set[0]).addCData(set[1]));
       }

} void main() {

       auto root = new XmlNode("");
       root.addChild(new XmlPI("xml"));
       addChars(root,characters);
       std.stdio.writefln("%s",root.write);

}</lang>

<?xml?>
<CharacterRemarks>
    <Character name="April">
        Bubbly: I'm &gt; Tam and &lt;= Emily
    </Character>
    <Character name="Tam O'Shanter">
        Burns: "When chapman billies leave the street ..."
    </Character>
    <Character name="Emily">
        Short &amp; shrift
    </Character>
</CharacterRemarks>

Delphi

<lang Delphi> //You need to use these units uses

 Classes,
 Dialogs,
 XMLIntf,
 XMLDoc;

//..............................................

//This function creates the XML function CreateXML(aNames, aRemarks: TStringList): string; var

 XMLDoc: IXMLDocument;
 Root: IXMLNode;
 i: Integer;

begin

 //Input check
 if (aNames   = nil) or
    (aRemarks = nil) then
 begin
    Result:= '<CharacterRemarks />';
    Exit;
 end;
 //Creating the TXMLDocument instance
 XMLDoc:= TXMLDocument.Create(nil);
 //Activating the document
 XMLDoc.Active:= True;
 //Creating the Root element
 Root:= XMLDoc.AddChild('CharacterRemarks');
 //Creating the inner nodes
 for i:=0 to Min(aNames.Count, aRemarks.Count) - 1 do
 with Root.AddChild('Character') do
 begin
   Attributes['name']:= aNames[i];
   Text:= aRemarks[i];
 end;
 //Outputting the XML as a string
 Result:= XMLDoc.XML.Text;

end;

//..............................................

//Consuming code example (fragment) var

 Names,
 Remarks: TStringList;

begin

 //Creating the lists objects
 Names:= TStringList.Create;
 Remarks:= TStringList.Create;
 try
   //Filling the list with names
   Names.Add('April');
   Names.Add('Tam OShanter');
   Names.Add('Emily');
   //Filling the list with remarks
   Remarks.Add('Bubbly: Im > Tam and <= Emily');
   Remarks.Add('Burns: "When chapman billies leave the street ..."');
   Remarks.Add('Short & shrift');
   //Constructing and showing the XML
   Showmessage(CreateXML(Names, Remarks));
 finally
   //Freeing the list objects
   Names.Free;
   Remarks.Free;
 end;

end;

</lang>

Euphoria

Translation of: BASIC

<lang euphoria>function xmlquote(sequence s)

   sequence r
   r = ""
   for i = 1 to length(s) do
       if s[i] = '<' then
           r &= "<"
       elsif s[i] = '>' then
           r &= ">"
       elsif s[i] = '&' then
           r &= "&"
       elsif s[i] = '"' then
           r &= """
       elsif s[i] = '\ then
           r &= "'"
       else
           r &= s[i]
       end if
   end for
   return r

end function

constant CharacterRemarks = {

   {"April", "Bubbly: I'm > Tam and <= Emily"},
   {"Tam O'Shanter", "Burns: \"When chapman billies leave the street ...\""},
   {"Emily", "Short & shrift"}

}

puts(1,"<CharacterRemarks>\n") for i = 1 to length(CharacterRemarks) do

   printf(1,"  <CharacterName=\"%s\">",{xmlquote(CharacterRemarks[i][1])})
   puts(1,xmlquote(CharacterRemarks[i][2]))
   puts(1,"</Character>\n")

end for puts(1,"</CharacterRemarks>\n")</lang>

Output: <lang xml><CharacterRemarks>

 <CharacterName="April">Bubbly: I'm > Tam and <= Emily</Character>
 <CharacterName="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character>
 <CharacterName="Emily">Short & shrift</Character>

</CharacterRemarks> </lang>

F#

<lang fsharp>#light

open System.Xml type Character = {name : string; comment : string }

let data = [

   { name = "April"; comment = "Bubbly: I'm > Tam and <= Emily"}
   { name = "Tam O'Shanter"; comment = "Burns: \"When chapman billies leave the street ...\""}
   { name = "Emily"; comment = "Short & shrift"} ]

let doxml (characters : Character list) =

   let doc = new XmlDocument()
   let root = doc.CreateElement("CharacterRemarks")
   doc.AppendChild root |> ignore
   Seq.iter (fun who ->
            let node = doc.CreateElement("Character")
            node.SetAttribute("name", who.name)
            doc.CreateTextNode(who.comment) 
            |> node.AppendChild |> ignore
            root.AppendChild node |> ignore
            ) characters
   doc.OuterXml</lang>
<CharacterRemarks>
 <Character name="April">Bubbly: I'm &gt; Tam and &lt;= Emily</Character>
 <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character>
 <Character name="Emily">Short &amp; shrift</Character>
</CharacterRemarks>

Factor

<lang factor>USING: sequences xml.syntax xml.writer ;

print-character-remarks ( names remarks -- )
   [ [XML <Character name=<-> ><-></Character> XML] ] 2map
   [XML <CharacterRemarks><-></CharacterRemarks> XML] pprint-xml ;</lang>

Example of usage: <lang factor>{ "April" "Tam O'Shanter" "Emily" } {

   "Bubbly: I'm > Tam and <= Emily"
   "Burns: \"When chapman billies leave the street ...\""
   "Short & shrift"

} print-remarks</lang>

Fantom

<lang fantom> using xml

class XmlOutput {

 public static Void main ()
 {
   Str[] names := ["April", "Tam O'Shanter", "Emily"]
     Str[] remarks := ["Bubbly: I'm > Tam and <= Emily",
       "Burns: \"When chapman billies leave the street ...\"",
       "Short & shrift"]
   doc := XDoc()
   root := XElem("CharacterRemarks")
   doc.add (root)
   names.each |Str name, Int i|
   {
     child := XElem("Character")
     child.addAttr("Name", name)
     child.add(XText(remarks[i]))
     root.add (child)
   }
   doc.write(Env.cur.out)
 }

} </lang>

Output (not exactly conforming):

<?xml version='1.0' encoding='UTF-8'?>
<CharacterRemarks>
 <Character Name='April'>Bubbly: I'm > Tam and &lt;= Emily</Character>
 <Character Name='Tam O&apos;Shanter'>Burns: "When chapman billies leave the street ..."</Character>
 <Character Name='Emily'>Short & shrift</Character>
</CharacterRemarks>

Forth

<lang forth>include ffl/est.fs include ffl/xos.fs

\ Input lists 0 value names here ," Emily" here ," Tam O'Shanter" here ," April" here to names , , ,

0 value remarks here ," Short & shrift" here ,\" Burns: \"When chapman billies leave the street ...\"" here ," Bubbly: I'm > Tam and <= Emily" here to remarks , , ,

s++ ( c-addr1 -- c-addr2 c-addr3 u3 )
 dup cell+ swap @ count

\ Create xml writer tos-create xml

create-xml ( c-addr1 c-addr2 -- )
 0 s" CharacterRemarks" xml xos-write-start-tag
 3 0 DO
   swap s++ s" name" 2swap 1 
   s" Character" xml xos-write-start-tag
   swap s++      xml xos-write-text
   s" Character" xml xos-write-end-tag
 LOOP
 drop drop
 s" CharacterRemarks" xml xos-write-end-tag

names remarks create-xml

\ Output xml string xml str-get type cr</lang>

Go

<lang go>package main

import (

   "bytes"
   "fmt"
   "os"
   "template"
   "xml"

)

type crm struct {

   Char, Rem string

}

var crms = []crm{

   {`April`, `Bubbly: I'm > Tam and <= Emily`},
   {`Tam O'Shanter`, `Burns: "When chapman billies leave the street ..."`},
   {`Emily`, `Short & shrift`}}

var tmpl = `<CharacterRemarks> Template:Range . <Character name="Template:Xml .Char">Template:Xml .Rem</Character> Template:End</CharacterRemarks> `

func xmlEscapeString(s string) string {

   var b bytes.Buffer
   xml.Escape(&b, []byte(s))
   return b.String()

}

func main() {

   xt := template.New("").Funcs(template.FuncMap{"xml": xmlEscapeString})
   template.Must(xt.Parse(tmpl))
   if err := xt.Execute(os.Stdout, crms); err != nil {
       fmt.Println(err)
   }

}</lang> Output: <lang xml><CharacterRemarks>

   <Character name="April">Bubbly: I'm > Tam and <= Emily</Character>
   <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character>
   <Character name="Emily">Short & shrift</Character>

</CharacterRemarks></lang>

Groovy

<lang groovy>def writer = new StringWriter() def builder = new groovy.xml.MarkupBuilder(writer) def names = ["April", "Tam O'Shanter", "Emily"] def remarks = ["Bubbly: I'm > Tam and <= Emily", 'Burns: "When chapman billies leave the street ..."', "Short & shrift"]

builder.CharacterRemarks() {

   names.eachWithIndex() { n, i -> Character(name:n, remarks[i]) };    

}

println writer.toString()</lang>

Haskell

This implementation uses the xml package.

<lang haskell>import Text.XML.Light

characterRemarks :: [String] -> [String] -> String characterRemarks names remarks = showElement $ Element

   (unqual "CharacterRemarks")
   []
   (zipWith character names remarks)
   Nothing
 where character name remark = Elem $ Element
           (unqual "Character")
           [Attr (unqual "name") name]
           [Text $ CData CDataText remark Nothing]
           Nothing</lang>

HicEst

<lang HicEst>CHARACTER names="April~Tam O'Shanter~Emily~" CHARACTER remarks*200/%Bubbly: I'm > Tam and <= Emily~Burns: "When chapman billies leave the street ..."~Short & shrift~%/ CHARACTER XML*1000

EDIT(Text=remarks, Right='&', RePLaceby='&', DO) EDIT(Text=remarks, Right='>', RePLaceby='>', DO) EDIT(Text=remarks, Right='<', RePLaceby='<', DO)

XML = "<CharacterRemarks>" // $CRLF DO i = 1, 3

 EDIT(Text=names, SePaRators='~', ITeM=i, Parse=name)
 EDIT(Text=remarks, SePaRators='~', ITeM=i, Parse=remark)
 XML = TRIM(XML) // '<Character name="' // name // '">' // remark // '</Character>' // $CRLF

ENDDO XML = TRIM(XML) // "</CharacterRemarks>"</lang>

J

First create the table of substitutions and the verb which properly escapes the input string:

<lang j>tbl=: ('&quote;'; '&'; '<'; '>') (a.i.'"&<>')} <"0 a. esc=: [:; {&tbl@:i.~&a.</lang>

Then create the verb which combines name with remark: <lang J>cmb=: [:; dyad define &.>

 '<Character name="', (esc x), '">', (esc y), '</Character>', LF

)</lang>

Finally, create the verb which creates the final XML: <lang j>xmlify=: '<CharacterRemarks>', LF, cmb, '</CharacterRemarks>'"_</lang>

Example:

<lang j>names=: 'April'; 'Tam OShanter'; 'Emily'

remarks=: <;._2]0 :0

I'm > Tam and <= Emily
Burns: "When chapman billies leave the street ..."
Short & shrift

)</lang>

<lang> names xmlify remarks <CharacterRemarks> <Character name="April"> I'm > Tam and <= Emily</Character> <Character name="Tam O'Shanter"> Burns: &quote;When chapman billies leave the street ...&quote;</Character> <Character name="Emily"> Short & shrift</Character> </CharacterRemarks></lang>

Java

Using DOM

<lang java>import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document; import org.w3c.dom.Element;

public class XmlCreation {

 private static final String[] names = {"April", "Tam O'Shanter", "Emily"};
 private static final String[] remarks = {"Bubbly: I'm > Tam and <= Emily",
   "Burns: \"When chapman billies leave the street ...\"",
     "Short & shrift"};
 
 public static void main(String[] args) {
   try {
     // Create a new XML document
     final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
     
     // Append the root element
     final Element root = doc.createElement("CharacterRemarks");
     doc.appendChild(root);
     
     // Read input data and create a new <Character> element for each name.
     for(int i = 0; i < names.length; i++) {
       final Element character = doc.createElement("Character");
       root.appendChild(character);
       character.setAttribute("name", names[i]);
       character.appendChild(doc.createTextNode(remarks[i]));
     }
     
     // Serializing XML in Java is unnecessary complicated
     // Create a Source from the document.
     final Source source = new DOMSource(doc);
     
     // This StringWriter acts as a buffer
     final StringWriter buffer = new StringWriter();
     
     // Create a Result as a transformer target.
     final Result result = new StreamResult(buffer);
     
     // The Transformer is used to copy the Source to the Result object. 
     final Transformer transformer = TransformerFactory.newInstance().newTransformer();
     transformer.setOutputProperty("indent", "yes");
     transformer.transform(source, result);
     
     // Now the buffer is filled with the serialized XML and we can print it 
     // to the console.
     System.out.println(buffer.toString());
   } catch (Exception e) {
     e.printStackTrace();
   }
 }
 

}</lang>

Result: <lang xml><?xml version="1.0" encoding="UTF-8" standalone="no"?> <CharacterRemarks> <Character name="April">Bubbly: I'm > Tam and <= Emily</Character> <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character> <Character name="Emily">Short & shrift</Character></lang>

Using the Streaming API for XML (StAX)

<lang java>import java.io.StringWriter;

import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamWriter;

public class XmlCreationStax {

 private static final String[] names = {"April", "Tam O'Shanter", "Emily"};
 private static final String[] remarks = {"Bubbly: I'm > Tam and <= Emily",
   "Burns: \"When chapman billies leave the street ...\"",
     "Short & shrift"};
 
 public static void main(String[] args) {
   try {
     final StringWriter buffer = new StringWriter();
     
     final XMLStreamWriter out = XMLOutputFactory.newInstance()
         .createXMLStreamWriter(buffer);
     out.writeStartDocument("UTF-8", "1.0");
     out.writeStartElement("CharacterRemarks");
     
     for(int i = 0; i < names.length; i++) {
       out.writeStartElement("Character");
       out.writeAttribute("name", names[i]);
       out.writeCharacters(remarks[i]);
       out.writeEndElement();
     }
     
     out.writeEndElement();
     out.writeEndDocument();
     
     System.out.println(buffer);
   } catch (Exception e) {
     e.printStackTrace();
   }
 }

}</lang>

This produces: <lang xml><?xml version="1.0" encoding="UTF-8"?><CharacterRemarks><Character name="April">Bubbly: I'm > Tam and <= Emily</Character><Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character><Character name="Emily">Short & shrift</Character></CharacterRemarks></lang>

NetRexx

Using DOM

Translation of: Java

<lang NetRexx>/* NetRexx */

options replace format comments java crossref savelog symbols nobinary

import java.io.StringWriter

import javax.xml.parsers.DocumentBuilderFactory import javax.xml.transform.Result import javax.xml.transform.Source import javax.xml.transform.Transformer import javax.xml.transform.TransformerFactory import javax.xml.transform.dom.DOMSource import javax.xml.transform.stream.StreamResult

import org.w3c.dom.Document import org.w3c.dom.Element

names = [String -

 "April", "Tam O'Shanter", "Emily" -

]

remarks = [ String -

    "Bubbly: I'm > Tam and <= Emily" -
 ,  'Burns: "When chapman billies leave the street ..."' -
 ,  'Short & shrift' -

]

do

 -- Create a new XML document
 doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()
 -- Append the root element
 root = doc.createElement("CharacterRemarks")
 doc.appendChild(root)
 -- Read input data and create a new <Character> element for each name.
 loop i_ = 0 to names.length - 1
   character = doc.createElement("Character")
   root.appendChild(character)
   character.setAttribute("name", names[i_])
   character.appendChild(doc.createTextNode(remarks[i_]))
   end i_
 -- Serializing XML in Java is unnecessary complicated
 -- Create a Source from the document.
 source = DOMSource(doc)
 -- This StringWriter acts as a buffer
 buffer = StringWriter()
 -- Create a Result as a transformer target.
 result = StreamResult(buffer)
 -- The Transformer is used to copy the Source to the Result object.
 transformer = TransformerFactory.newInstance().newTransformer()
 transformer.setOutputProperty("indent", "yes")
 transformer.transform(source, result)
 -- Now the buffer is filled with the serialized XML and we can print it to the console.
 say buffer.toString

catch ex = Exception

 ex.printStackTrace

end

return </lang>

Output

<lang xml><?xml version="1.0" encoding="UTF-8" standalone="no"?> <CharacterRemarks> <Character name="April">Bubbly: I'm > Tam and <= Emily</Character> <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character> <Character name="Emily">Short & shrift</Character> </CharacterRemarks> </lang>

Using the Streaming API for XML (StAX)

Translation of: Java

<lang NetRexx>/* NetRexx */

options replace format comments java crossref savelog symbols nobinary

import java.io.StringWriter

import javax.xml.stream.XMLOutputFactory import javax.xml.stream.XMLStreamWriter

names = [String -

 "April", "Tam O'Shanter", "Emily" -

]

remarks = [ String -

    "Bubbly: I'm > Tam and <= Emily" -
 ,  'Burns: "When chapman billies leave the street ..."' -
 ,  'Short & shrift' -

]

do

 buffer = StringWriter()
 out = XMLOutputFactory.newInstance().createXMLStreamWriter(buffer)
 out.writeStartDocument("UTF-8", "1.0")
 out.writeCharacters('\n')
 out.writeStartElement("CharacterRemarks")
 out.writeCharacters('\n')
 loop i_ = 0 to names.length - 1
   out.writeStartElement("Character")
   out.writeAttribute("name", names[i_])
   out.writeCharacters(remarks[i_])
   out.writeEndElement()
   out.writeCharacters('\n')
   end i_
 out.writeEndElement()
 out.writeEndDocument()
 out.writeCharacters('\n')
 say buffer.toString

catch ex = Exception

 ex.printStackTrace

end

return </lang>

Output

<lang xml><?xml version="1.0" encoding="UTF-8"?> <CharacterRemarks> <Character name="April">Bubbly: I'm > Tam and <= Emily</Character> <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character> <Character name="Emily">Short & shrift</Character> </CharacterRemarks> </lang>

Objeck

<lang objeck> use XML; use Structure;

bundle Default {

 class Test {
   function : Main(args : String[]) ~ Nil {
     # list of name
     names := Vector->New();
     names->AddBack("April"->As(Base));
     names->AddBack("Tam O'Shanter"->As(Base));
     names->AddBack("Emily"->As(Base));
     # list of comments
     comments := Vector->New();
     comments->AddBack("Bubbly: I'm > Tam and <= Emily"->As(Base));
     comments->AddBack("Burns: \"When chapman billies leave the street ...\""->As(Base));
     comments->AddBack("Short & shrift"->As(Base));
     # build XML document
     builder := XMLBuilder->New("CharacterRemarks");
     root := builder->GetRoot();
     if(names->Size() = comments->Size()) {
       each(i : names) {
         element := XMLElement->New(XMLElementType->ELEMENT, 
           names->Get(i)->As(String), 
           comments->Get(i)->As(String));
         root->AddChild(element);
       };
     };      
     XMLElement->DecodeString(builder->ToString())->PrintLine();
   }
 }

} </lang>

OCaml

from the toplevel using the library xml-light:

<lang ocaml># #directory "+xml-light" (* or maybe "+site-lib/xml-light" *) ;;

  1. #load "xml-light.cma" ;;
  1. let data = [
   ("April", "Bubbly: I'm > Tam and <= Emily");
   ("Tam O'Shanter", "Burns: \"When chapman billies leave the street ...\"");
   ("Emily", "Short & shrift");
 ] in
 let tags =
   List.map (fun (name, comment) ->
     Xml.Element ("Character", [("name", name)], [(Xml.PCData comment)])
   ) data
 in
 print_endline (
   Xml.to_string_fmt (Xml.Element ("CharacterRemarks", [], tags)))
 ;;

<CharacterRemarks>

 <Character name="April">Bubbly: I'm > Tam and <= Emily</Character>
 <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character>
 <Character name="Emily">Short & shrift</Character>

</CharacterRemarks> - : unit = ()</lang>

Another solution using the library xmlm:

<lang ocaml>#directory "+xmlm"

  1. load "xmlm.cmo"

open Xmlm

let datas = [

   ("April", "Bubbly: I'm > Tam and <= Emily");
   ("Tam O'Shanter", "Burns: \"When chapman billies leave the street ...\"");
   ("Emily", "Short & shrift");
 ]

let xo = make_output (`Channel stdout)

let () =

 output xo (`Dtd None);
 output xo (`El_start (("", "CharacterRemarks"), []));
 List.iter (fun (name, content) ->
     output xo (`El_start (("", "Character"), [(("", "name"), name)]));
     output xo (`Data content);
     output xo (`El_end);
 ) datas;
 output xo (`El_end);
 print_newline()</lang>

Oz

It is natural to represent XML document as nested Oz records. Writing a function that serializes records to textual XML is not too difficult.

<lang oz>declare

 proc {Main}
    Names = ["April"

"Tam O'Shanter" "Emily"]

    Remarks = ["Bubbly: I'm > Tam and <= Emily"

"Burns: \"When chapman billies leave the street ...\"" "Short & shrift"]

    Characters = {List.zip Names Remarks

fun {$ N R} 'Character'(name:N R) end}

    DOM = {List.toTuple 'CharacterRemarks' Characters}
 in
    {System.showInfo {Serialize DOM}}
 end
 fun {Serialize DOM}
    "<?xml version=\"1.0\" ?>\n"#
    {SerializeElement DOM 0}
 end
 fun {SerializeElement El Indent}
    Name = {Label El}
    Attributes ChildElements Contents
    {DestructureElement El ?Attributes ?ChildElements ?Contents}
    EscContents = {Map Contents Escape}
    Spaces = {List.make Indent} for S in Spaces do S = &  end
 in
    Spaces#"<"#Name#
    {VSConcatMap Attributes SerializeAttribute}#">"#
    {VSConcat EscContents}#{When ChildElements\=nil "\n"}#
    {VSConcatMap ChildElements fun {$ E} {SerializeElement E Indent+4} end}#
    {When ChildElements\=nil Spaces}#"</"#Name#">\n"
 end
 proc {DestructureElement El ?Attrs ?ChildElements ?Contents}
    SubelementRec AttributeRec
    {Record.partitionInd El fun {$ I _} {Int.is I} end
     ?SubelementRec ?AttributeRec}
    Subelements = {Record.toList SubelementRec}
 in
    {List.partition Subelements VirtualString.is ?Contents ?ChildElements}
    Attrs = {Record.toListInd AttributeRec}
 end
 fun {SerializeAttribute Name#Value}
    " "#Name#"=\""#{EscapeAttribute Value}#"\""
 end
 fun {Escape VS}
    {Flatten {Map {VirtualString.toString VS} EscapeChar}}
 end
 fun {EscapeAttribute VS}
    {Flatten {Map {VirtualString.toString VS} EscapeAttributeChar}}
 end
 fun {EscapeChar X}
    case X of 60 then "<"
    [] 62 then ">"
    [] 38 then "&"
    else X
    end
 end
 fun {EscapeAttributeChar X}
    case X of 34 then """
    else {EscapeChar X}
    end
 end
 %% concatenates a list to a virtual string
 fun {VSConcat Xs}
    {List.toTuple '#' Xs}
 end
 fun {VSConcatMap Xs F}
    {VSConcat {Map Xs F}}
 end
 fun {When Cond X}
    if Cond then X else nil end 
 end

in

 {Main}</lang>

Output: <lang xml><?xml version="1.0" ?> <CharacterRemarks>

   <Character name="April">Bubbly: I'm > Tam and <= Emily</Character>
   <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character>
   <Character name="Emily">Short & shrift</Character>

</CharacterRemarks></lang>

Perl

Library: XML::MiniMini

<lang perl>#! /usr/bin/perl use strict; use XML::Mini::Document;

my @students = ( [ "April", "Bubbly: I'm > Tam and <= Emily" ],

                [ "Tam O'Shanter", "Burns: \"When chapman billies leave the street ...\"" ],

[ "Emily", "Short & shrift" ]

               );

my $doc = XML::Mini::Document->new(); my $root = $doc->getRoot(); my $studs = $root->createChild("CharacterRemarks"); foreach my $s (@students) {

   my $stud = $studs->createChild("Character");
   $stud->attribute("name", $s->[0]);
   $stud->text($s->[1]);

} print $doc->toString();</lang>

PicoLisp

<lang PicoLisp>(load "@lib/xm.l")

(de characterRemarks (Names Remarks)

  (xml
     (cons
        'CharacterRemarks
        NIL
        (mapcar
           '((Name Remark)
              (list 'Character (list (cons 'name Name)) Remark) )
           Names
           Remarks ) ) ) )

(characterRemarks

  '("April" "Tam O'Shanter" "Emily")
  (quote
     "I'm > Tam and <= Emily"
     "Burns: \"When chapman billies leave the street ..."
     "Short & shrift" ) )</lang>

Output:

<CharacterRemarks>
   <Character name="April">I'm > Tam and <= Emily</Character>
   <Character name="Tam O'Shanter">Burns: "When chapman billies leave the st
   <Character name="Emily">Short & shrift</Character>
</CharacterRemarks>

PureBasic

input lines are in separate files names.txt and remarks.txt. Output-XML is written to file demo.xml . <lang Purebasic> Structure characteristic

 name.s
 remark.s

EndStructure NewList didel.characteristic() If ReadFile(0, GetCurrentDirectory()+"names.txt")

 While Eof(0) = 0         
   AddElement(didel())
   didel()\name = ReadString(0)   
 Wend
 CloseFile(0)    

EndIf ResetList(didel()) FirstElement(didel()) If ReadFile(0, GetCurrentDirectory()+"remarks.txt")

 While Eof(0) = 0      
   didel()\remark = ReadString(0)  
   NextElement(didel())
 Wend
 CloseFile(0)        

EndIf ResetList(didel()) FirstElement(didel())

xml = CreateXML(#PB_Any) 
 mainNode = CreateXMLNode(RootXMLNode(xml)) 
 SetXMLNodeName(mainNode, "CharacterRemarks") 
  ForEach didel()
     item = CreateXMLNode(mainNode)
     SetXMLNodeName(item, "Character") 
     SetXMLAttribute(item, "name", didel()\name) 
     SetXMLNodeText(item, didel()\remark) 
   Next
FormatXML(xml, #PB_XML_ReFormat |  #PB_XML_WindowsNewline | #PB_XML_ReIndent)
SaveXML(xml, "demo.xml")

</lang>

Python

Normal output is all one line of XML, the .replace(...) makes it more readable. <lang python>>>> from xml.etree import ElementTree as ET >>> from itertools import izip >>> def characterstoxml(names, remarks): root = ET.Element("CharacterRemarks") for name, remark in izip(names, remarks): c = ET.SubElement(root, "Character", {'name': name}) c.text = remark return ET.tostring(root)

>>> print characterstoxml( names = ["April", "Tam O'Shanter", "Emily"], remarks = [ "Bubbly: I'm > Tam and <= Emily", 'Burns: "When chapman billies leave the street ..."', 'Short & shrift' ] ).replace('><','>\n<')</lang> Gives the output: <lang xml><CharacterRemarks> <Character name="April">Bubbly: I'm > Tam and <= Emily</Character> <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character> <Character name="Emily">Short & shrift</Character> </CharacterRemarks></lang>

R

Library: XML

<lang R>library(XML) char2xml <- function(names, remarks){ tt <- xmlHashTree() head <- addNode(xmlNode("CharacterRemarks"), character(), tt) node <- list() for (i in 1:length(names)){ nodei <- addNode(xmlNode("Character", attrs=c(name=names[i])), head, tt) addNode(xmlTextNode(remarks[i]), nodei, tt) } return(tt) } output <- char2xml( names=c("April","Tam O'Shanter","Emily"), remarks=c("Bubbly: I'm > Tam and <= Emily", 'Burns: "When chapman billies leave the street ..."', "Short & shrift") )</lang>

Gives the output:

<CharacterRemarks>
 <Character name="April">Bubbly: I'm &gt; Tam and &lt;= Emily</Character>
 <Character name="Tam O'Shanter">Burns: &quot;When chapman billies leave the street ...&quot;</Character>
 <Character name="Emily">Short &amp; shrift</Character>
</CharacterRemarks>

REXX

REXX doesn't have any functions to handle XML entities, an abbreviated version is included here. <lang rexx> /*REXX program to create a list of character names & remarks. */

charname.= charname.1="April" charname.2="Tam O'Shanter" charname.3="Emily"

 do j=1 while charname.j\==
 say 'charname' j '=' charname.j
 end

say

remark.= remark.1="I'm > Tam and <= Emily" remark.2="When chapman billies leave the street ..." remark.3="Short & shift"

 do j=1 while remark.j\==
 say '  remark' j '=' remark.j
 end

say

items=0 header='CharacterRemarks' header=header'>'

 do j=1 while charname.j\==
 _=charname.j
 if j==1 then call create '<'header
 call create '    <Character name="' ||,
             char2xml(_)'">"' ||,
             char2xml(remark.j)'"</Character>'
 end   /*j*/

if create.0\==0 then call create '</'header

 do k=1 for create.0
 say create.k
 end

exit

/*─────────────────────────────────────CREATE subroutine────────────────*/ create: items=items+1 /*bump the count of items in list*/ create.items=arg(1) /*add item to the CREATE list. */ create.0=items /*indicate how many items in list*/ return

/*─────────────────────────────────────XML_ subroutine──────────────────*/ xml_: parse arg _ /*make an XML entity (&xxxx;) */ if pos(_,x)\==0 then return changestr(_,x,"&"arg(2)";") return x

/*─────────────────────────────────────CHAR2XML subroutine──────────────*/ char2xml: procedure; parse arg x a=pos('&',x)\==0 /*ampersands have to be treated special.*/ b=pos(';',x)\==0 /*semicolons have to be treated special.*/ xml0=0

if a\==0 then do

             a=1    /*below, find a free character to translate freely.*/
               do j=0 to 254; ?=d2c(j); if pos(?,x)==0 then leave; end
             x=translate(x,?,"&");xml0=j+1
             end

if b\==0 then do

             b=1    /*below, find a free character to translate freely.*/
               do j=xml0 to 254; ??=d2c(j); if pos(??,x)==0 then leave; end
             x=translate(x,??,";")
             end
                               /*Following are a few of the chars in   */
                               /*the DOS (DOS under Windows)  codepage.*/

x=xml_('♥',"hearts") x=xml_('♦',"diams") x=xml_('♣',"clubs") x=xml_('♠',"spades") x=xml_('♂',"male") x=xml_('♀',"female") x=xml_('↕',"UpDownArrow") x=xml_('¶',"para") x=xml_('§',"sect") x=xml_('↑',"uarr") x=xml_('↓',"darr") x=xml_('←',"larr") x=xml_('1c'x,"rarr") x=xml_('!',"excl") x=xml_('!',"excl") x=xml_('"',"apos") x=xml_('$',"dollar") x=xml_("'","quot") x=xml_('*',"ast") x=xml_('/',"sol") x=xml_(':',"colon") x=xml_('<',"lt") x=xml_('=',"equals") x=xml_('>',"gt") x=xml_('@',"commat") x=xml_('[',"lbrack") x=xml_('\',"bsol") x=xml_(']',"rbrack") x=xml_('^',"Hat") x=xml_('`',"grave") x=xml_('{',"lbrace") x=xml_('|',"vert") x=xml_('}',"rbrace") x=xml_('Ç',"Ccedil") x=xml_('Ç','#x00c7') x=xml_('ü',"uuml") x=xml_('ü','#x00fc') x=xml_('é',"eacute") x=xml_('é','#x00e9') x=xml_('â',"acirc") x=xml_('â',"ETH") x=xml_('â','#x00e2') x=xml_('â','#x00e9') x=xml_('ä',"auml") x=xml_('ä','#x00e4') x=xml_('à',"agrave") x=xml_('à','#x00e0') x=xml_('å',"aring") x=xml_('å','#x00e5') x=xml_('ç',"ccedil") x=xml_('ç','#x00e7') x=xml_('ê',"ecirc") x=xml_('ê','#x00ea') x=xml_('ë',"euml") x=xml_('ë','#x00eb') x=xml_('è',"egrave") x=xml_('è','#x00e8') x=xml_('ï',"iuml") x=xml_('ï','#x00ef') x=xml_('î',"icirc") x=xml_('î','#x00ee') x=xml_('ì',"igrave") x=xml_('ì','#x00ec') x=xml_('Ä',"Auml") x=xml_('Ä','#x00c4') x=xml_('Å',"Aring") x=xml_('Å',"Aring") x=xml_('Å','#x00c5') x=xml_('É',"Eacute") x=xml_('É','#x00c9') x=xml_('æ',"aelig") x=xml_('æ','#x00e6') x=xml_('Æ',"AElig") x=xml_('Æ','#x00c6') x=xml_('ô',"ocirc") x=xml_('ô','#x00f4') x=xml_('ö',"ouml") x=xml_('ö','#x00f6') x=xml_('ò',"ograve") x=xml_('ò','#x00f2') x=xml_('û',"ucirc") x=xml_('û','#x00fb') x=xml_('ù',"ugrave") x=xml_('ù','#x00f9') x=xml_('ÿ',"yuml") x=xml_('ÿ','#x00ff') x=xml_('Ö',"Ouml") x=xml_('Ö','#x00d6') x=xml_('Ü',"Uuml") x=xml_('Ü','#x00dc') x=xml_('¢',"cent") x=xml_('£',"pound") x=xml_('¥',"yen") x=xml_('ƒ',"fnof") x=xml_('á',"aacute") x=xml_('á','#x00e1') x=xml_('í',"iacute") x=xml_('í','#x00ed') x=xml_('ó',"oacute") x=xml_('ó','#x00f3') x=xml_('ú',"uacute") x=xml_('ú','#x00fa') x=xml_('ñ',"ntilde") x=xml_('ñ','#x00f1') x=xml_('Ñ',"Ntilde") x=xml_('Ñ','#x00d1') x=xml_('¿',"iquest") x=xml_('⌐',"bnot") x=xml_('¬',"not") x=xml_('½',"fact12") x=xml_('¼',"fact14") x=xml_('¡',"iexcl") x=xml_('«',"laqru") x=xml_('»',"raqru") x=xml_('α',"alpha") x=xml_('ß',"beta") x=xml_('ß',"szlig") x=xml_('ß','#x00df') x=xml_('Γ',"Gamma") x=xml_('π',"pi") x=xml_('π',"pi") x=xml_('Σ',"Sigma") x=xml_('σ',"sigma") x=xml_('µ',"mu") x=xml_('τ',"tau") x=xml_('Φ',"phi") x=xml_('Θ',"Theta") x=xml_('δ',"delta") x=xml_('∞',"infin") x=xml_('φ',"Phi") x=xml_('ε',"epsilon") x=xml_('∩',"cap") x=xml_('≡',"equiv") x=xml_('±',"plusmn") x=xml_('≥',"ge") x=xml_('≤',"le") x=xml_('÷',"div") x=xml_('≈',"approx") x=xml_('∙',"bull") x=xml_('°',"deg") x=xml_('·',"middot") x=xml_('√',"radic") x=xml_('²',"sup2") x=xml_('■',"squart ")

if a then x=xml_(?,"amp") /*if we had an ampersand, translate it now.*/ if b then x=xml_(??,"semi") /*if we had a semicolon, translate it now.*/ return x </lang> Output:

charname 1 = April
charname 2 = Tam O'Shanter
charname 3 = Emily

  remark 1 = I'm > Tam and <= Emily
  remark 2 = When chapman billies leave the street ...
  remark 3 = Short & shift

<CharacterRemarks>
    <Character name="April">"I"m > Tam and <= Emily"</Character>
    <Character name="Tam O"Shanter">"When chapman billies leave the street ..."</Character>
    <Character name="Emily">"Short & shift"</Character>
</CharacterRemarks>

Ruby

The

Library: REXML

library handles character mapping when adding attributes and text.

<lang ruby>require 'rexml/document' include REXML

remarks = {

 %q(April)         => %q(Bubbly: I'm > Tam and <= Emily),
 %q(Tam O'Shanter) => %q(Burns: "When chapman billies leave the street ..."),
 %q(Emily)         => %q(Short & shrift),

}

doc = Document.new root = doc.add_element("CharacterRemarks")

remarks.each do |name, remark|

 root.add_element("Character", {'Name' => name}).add_text(remark)

end

  1. output with indentation

doc.write($stdout, 2)</lang>

produces

<CharacterRemarks>
  <Character Name='Emily'>
    Short &amp; shrift
  </Character>
  <Character Name='Tam O&apos;Shanter'>
    Burns: &quot;When chapman billies leave the street ...&quot;
  </Character>
  <Character Name='April'>
    Bubbly: I&apos;m &gt; Tam and &lt;= Emily
  </Character>
</CharacterRemarks>

Scala

<lang scala>val names = List("April", "Tam O'Shanter", "Emily")

val remarks = List("Bubbly: I'm > Tam and <= Emily", """Burns: "When chapman billies leave the street ..."""", "Short & shrift")

def characterRemarks(names: List[String], remarks: List[String]) = <CharacterRemarks>

 { names zip remarks map { case (name, remark) => <Character name={name}>{remark}</Character> } }

</CharacterRemarks>


characterRemarks(names, remarks) </lang>

Result: <lang xml><CharacterRemarks>

 <Character name="April">Bubbly: I'm > Tam and <= Emily</Character><Character name="Tam O'Shanter">Burns: 

"When chapman billies leave the street ..."</Character><Character name="Emily">Short & shrift</Character> </CharacterRemarks></lang>

Slate

<lang slate>lobby define: #remarks -> ( {'April' -> 'Bubbly: I\'m > Tam and <= Emily'. 'Tam O\'Shanter' -> 'Burns: "When chapman billies leave the street ..."'. 'Emily' -> 'Short & shrift'. } as: Dictionary).

define: #writer -> (Xml Writer newOn: new writer). writer inTag: 'CharacterRemarks' do:

 [| :w |
  lobby remarks keysAndValuesDo:
    [| :name :remark | w inTag: 'Character' do: [| :w | w ; remark] &attributes: {'name' -> name}].
  ].

inform: writer contents</lang> Produces:

<CharacterRemarks><Character name="Emily">Short & shrift</Character><Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character><Character name="April">Bubbly: I'm > Tam and <= Emily</Character></CharacterRemarks>

Tcl

Using only Tcl string manipulation

<lang Tcl>proc xquote string {

   list [string map "' ' \\\" " < > > < & &" $string]

} proc < {name attl args} {

   set res <$name
   foreach {att val} $attl {
       append res " $att='$val'"
   }
   if {[llength $args]} {
       append res >
       set sep ""
       foreach a $args {
           append res $sep $a
           set sep \n
       } 
       append res </$name>
   } else {append res />}
   return $res

} set cmd {< CharacterRemarks {}} foreach {name comment} {

   April "Bubbly: I'm > Tam and <= Emily"
   "Tam O'Shanter" "Burns: \"When chapman billies leave the street ...\""
   Emily "Short & shrift"

} {

   append cmd " \[< Character {Name [xquote $name]} [xquote $comment]\]"

} puts [eval $cmd]</lang>

produces

<CharacterRemarks><Character Name='April'>Bubbly: I&apos;m &lt; Tam and &gt;= Emily</Character>
<Character Name='Tam O&apos;Shanter'>Burns: &quot;When chapman billies leave the street ...&quot;</Character>
<Character Name='Emily'>Short &amp; shrift</Character></CharacterRemarks>

Working with DOM trees

Using

Library: tDOM

<lang tcl>package require tdom set xml [dom createDocument CharacterRemarks] foreach {name comment} {

   April "Bubbly: I'm > Tam and <= Emily"
   "Tam O'Shanter" "Burns: \"When chapman billies leave the street ...\""
   Emily "Short & shrift"

} {

   set elem [$xml createElement Character]
   $elem setAttribute name $name
   $elem appendChild [$xml createTextNode $comment]
   [$xml documentElement] appendChild $elem

} $xml asXML</lang>

<CharacterRemarks>
    <Character name="April">Bubbly: I'm &amp;gt; Tam and &amp;lt;= Emily</Character>
    <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character>
    <Character name="Emily">Short &amp; shrift</Character>
</CharacterRemarks>

Using

Library: TclXML

<lang tcl>package require dom set xml [dom::DOMImplementation create] set root [dom::document createElement $xml CharacterRemarks] foreach {name comment} {

   April "Bubbly: I'm > Tam and <= Emily"
   "Tam O'Shanter" "Burns: \"When chapman billies leave the street ...\""
   Emily "Short & shrift"

} {

   set element [dom::document createElement $root Character]
   dom::element setAttribute $element name $name
   dom::document createTextNode $element $comment

} dom::DOMImplementation serialize $xml -indent 1</lang> produces (with line breaks added for clarity:

<?xml version="1.0"?>
<CharacterRemarks>
  <Character name="April">Bubbly: I'm &gt; Tam and &lt;= Emily</Character>
  <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character>
  <Character name="Emily">Short &amp; shrift</Character>
</CharacterRemarks>

TUSCRIPT

<lang tuscript> $$ MODE TUSCRIPT STRUCTURE xmloutput DATA '<CharacterRemarks>' DATA * ' <Character name="' names +'">' remarks +'</Character>' DATA = '</CharacterRemarks>' ENDSTRUCTURE BUILD X_TABLE entitysubst=" >> > << < & & " ERROR/STOP CREATE ("dest",seq-o,-std-) ACCESS d: WRITE/ERASE/STRUCTURE "dest" num,str str="xmloutput"

 names=*
 DATA April
 DATA Tam O'Shanter
 DATA Emily
 remarks=*
 DATA Bubbly: I'm > Tam and <= Emily
 DATA Burns: "When chapman billies leave the street ..."
 DATA Short & shrift
 remarks=EXCHANGE(remarks,entitysubst)

WRITE/NEXT d ENDACCESS d </lang> Output in file "dest":

<CharacterRemarks>
  <Character name="April">Bubbly: I'm > Tam and <= Emily</Character>
  <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street ..."</Character>
  <Character name="Emily">Short & shrift</Character>
</CharacterRemarks>  

Vedit macro language

The input data is given in an edit buffer, one name+remark pair on each line line, separated with TAB character. <lang vedit>// Replace special characters with entities: Replace("&", "&", BEGIN+ALL+NOERR) // this must be the first replace! Replace("<", "<", BEGIN+ALL+NOERR) Replace(">", ">", BEGIN+ALL+NOERR) Replace("'", "'", BEGIN+ALL+NOERR) Replace('"', """, BEGIN+ALL+NOERR)

// Insert XML marking BOF IT("<CharacterRemarks>") IN Repeat(ALL) {

   Search("^.", REGEXP+ERRBREAK)
   IT('  <Character name="')
   Replace('|T', '">')
   EOL IT('</Character>')

} EOF IT("</CharacterRemarks>") IN</lang>

Example input:

April	Bubbly: I'm > Tam and <= Emily
Tam O'Shanter	Burns: "When chapman billies leave the street ..." 
Emily	Short & shrift

Produces this output:

<CharacterRemarks>
  <Character name="April">Bubbly: I&apos;m &gt; Tam and &lt;= Emily</Character>
  <Character name="Tam O&apos;Shanter">Burns: &quot;When chapman billies leave the street ...&quot; </Character>
  <Character name="Emily">Short &amp; shrift</Character>
</CharacterRemarks>

Visual Basic .NET

<lang vbnet>Module XMLOutput

   Sub Main()
       Dim charRemarks As New Dictionary(Of String, String)
       charRemarks.Add("April", "Bubbly: I'm > Tam and <= Emily")
       charRemarks.Add("Tam O'Shanter", "Burns: ""When chapman billies leave the street ...""")
       charRemarks.Add("Emily", "Short & shrift")
       Dim xml = <CharacterRemarks>
                     <%= From cr In charRemarks Select <Character name=<%= cr.Key %>><%= cr.Value %></Character> %>
                 </CharacterRemarks>
       Console.WriteLine(xml)
   End Sub

End Module</lang>

Output:

<CharacterRemarks>
  <Character name="April">Bubbly: I'm &gt; Tam and &lt;= Emily</Character>
  <Character name="Tam O'Shanter">Burns: "When chapman billies leave the street..."</Character>
  <Character name="Emily">Short &amp; shrift</Character>
</CharacterRemarks>