XML/Output

From Rosetta Code
< XML
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):

<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>

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[edit]

Works with: GNAT

Uses XML/Ada from AdaCore.

character_remarks.adb:

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;

Alternative version using Matreshka[edit]

Uses Matreshka SAX API for XML.

with Ada.Wide_Wide_Text_IO;
 
with League.Strings;
with XML.SAX.Attributes;
with XML.SAX.Pretty_Writers;
 
procedure Main is
 
function "+"
(Item : Wide_Wide_String) return League.Strings.Universal_String
renames League.Strings.To_Universal_String;
 
type Remarks is record
Name  : League.Strings.Universal_String;
Remark : League.Strings.Universal_String;
end record;
 
type Remarks_Array is array (Positive range <>) of Remarks;
 
------------
-- Output --
------------
 
procedure Output (Remarks : Remarks_Array) is
Writer  : XML.SAX.Pretty_Writers.SAX_Pretty_Writer;
Attributes : XML.SAX.Attributes.SAX_Attributes;
 
begin
Writer.Set_Offset (2);
Writer.Start_Document;
Writer.Start_Element (Qualified_Name => +"CharacterRemarks");
 
for J in Remarks'Range loop
Attributes.Clear;
Attributes.Set_Value (+"name", Remarks (J).Name);
Writer.Start_Element
(Qualified_Name => +"Character", Attributes => Attributes);
Writer.Characters (Remarks (J).Remark);
Writer.End_Element (Qualified_Name => +"Character");
end loop;
 
Writer.End_Element (Qualified_Name => +"CharacterRemarks");
Writer.End_Document;
 
Ada.Wide_Wide_Text_IO.Put_Line (Writer.Text.To_Wide_Wide_String);
end Output;
 
begin
Output
(((+"April", +"Bubbly: I'm > Tam and <= Emily"),
(+"Tam O'Shanter", +"Burns: ""When chapman billies leave the street ..."""),
(+"Emily", +"Short & shrift")));
end Main;

ALGOL 68[edit]

# returns a translation of str suitable for attribute values and content in an XML document #
OP TOXMLSTRING = ( STRING str )STRING:
BEGIN
STRING result := "";
FOR pos FROM LWB str TO UPB str DO
CHAR c = str[ pos ];
result +:= IF c = "<" THEN "&lt;"
ELIF c = ">" THEN "&gt;"
ELIF c = "&" THEN "&amp;"
ELIF c = "'" THEN "&apos;"
ELIF c = """" THEN "&quot;"
ELSE c
FI
OD;
result
END; # TOXMLSTRING #
 
# generate a CharacterRemarks XML document from the characters and remarks #
# the number of elements in characters and remrks must be equal - this is not checked #
# the <?xml?> element is not generated #
PROC generate character remarks document = ( []STRING characters, remarks )STRING:
BEGIN
STRING result := "<CharacterRemarks>";
INT remark pos := LWB remarks;
FOR char pos FROM LWB characters TO UPB characters DO
result +:= "<Character name=""" + TOXMLSTRING characters[ char pos ] + """>"
+ TOXMLSTRING remarks[ remark pos ]
+ "</Character>"
+ REPR 10
;
remark pos +:= 1
OD;
result +:= "</CharacterRemarks>";
result
END; # generate character remarks document #
 
# test the generation #
print( ( generate character remarks document( ( "April", "Tam O'Shanter", "Emily" )
, ( "Bubbly: I'm > Tam and <= Emily"
, "Burns: ""When chapman billies leave the street ..."
, "Short & shrift"
)
)
, newline
)
)
 
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 ...</Character>
<Character name="Emily">Short &amp; shrift</Character>
</CharacterRemarks>

AutoHotkey[edit]

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 = &quot;,&gt;,&lt;,&lt;=,&gt;=,&apos;,&amp;
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:
#LTrim
names =
(
April
Tam O'Shanter
Emily
)
 
remarks =
(
Bubbly: I'm > Tam and <= Emily
Burns: "When chapman billies leave the street ..."
Short & shrift
)
return

BASIC[edit]

Works with: FreeBASIC
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 + "&lt;"
Case Asc(">")
r = r + "&gt;"
Case Asc("&")
r = r + "&amp;"
Case Asc("""")
r = r + "&quot;"
Case Asc("'")
r = r + "&apos;"
Case Else
r = r + c
End Select
Next
Function = r
End Function

Applesoft BASIC[edit]

100 Q$ = CHR$(34)
110 DE$(0) = "April"
120 RE$(0) = "Bubbly: I'm > Tam and <= Emily"
130 DE$(1) = "Tam O'Shanter"
140 RE$(1) = "Burns: " + Q$ + "When chapman billies leave the street ..." + Q$
150 DE$(2) = "Emily"
160 RE$(2) = "Short & shrift"
 
200 Print "<CharacterRemarks>"
210 For I = 0 to 2
220 Print " <Character name="Q$;
230 X$=DE$(I) : GOSUB 300xmlquote
240 PRINT Q$">";
250 X$=RE$(I) : GOSUB 300xmlquote
260 PRINT "</Character>"
270 Next
280 Print "</CharacterRemarks>"
290 End
 
300 For n = 1 To Len(X$)
310 c$ = Mid$(X$,n,1)
320 IF C$ = "<" THEN C$ = "&lt;"
330 IF C$ = ">" THEN C$ = "&gt;"
340 IF C$ = "&" THEN C$ = "&amp;"
350 IF C$ = Q$ THEN C$ = "&quot;"
360 IF C$ = "'" THEN C$ = "&apos;"
370 PRINT C$;
380 NEXT N
390 RETURN

Bracmat[edit]

( ( 2XML
= PCDATAentities attributeValueEntities doAll doAttributes
, xml
. ( attributeValueEntities
= a c
. @( !arg
 :  ?a
(("<"|"&"|\"):?c)
 ?arg
)
&  !a
"&"
( !c:"<"&lt
| !c:"&"&amp
| quot
)
";"
attributeValueEntities$!arg
| !arg
)
& ( PCDATAentities
= a c
. @( !arg
 :  ?a
(("<"|"&"|">"):?c)
 ?arg
)
&  !a
"&"
( !c:"<"&lt
| !c:"&"&amp
| gt
)
";"
PCDATAentities$!arg
| !arg
)
& ( doAttributes
= a v
.  !arg:(?a.?v) ?arg
& " "
PCDATAentities$!a
"=\""
attributeValueEntities$!v
\"
doAttributes$!arg
|
)
& ( doAll
= xml first A B C att XML
.  !arg:?xml
& :?XML
& whl
' ( !xml:%?first ?xml
& (  !first:(?A.?B)
& (  !B:(?att,?C)
&  !XML
(  !C:
& "<" !A doAttributes$!att " />\n"
| "<"
 !A
doAttributes$!att
">"
doAll$!C
"</"
 !A
">\n"
)
 : ?XML
|  !A
 : ( "!"&!XML "<!" !B ">":?XML
| "!--"
& !XML "<!--" !B "-->":?XML
| "?"&!XML "<?" !B "?>\n":?XML
| "![CDATA["
& !XML "<![CDATA[" !B "]]>":?XML
| "!DOCTYPE"
& !XML "<!DOCTYPE" !B ">":?XML
|  ?
& !XML "<" !A doAttributes$!B ">":?XML
)
)
| !XML PCDATAentities$!first:?XML
)
)
& str$!XML
)
& doAll$!arg
)
& ( makeList
= characters name names remark remarks
.  !arg:(?names.?remarks)
& :?characters
& whl
' ( (!names.!remarks)
 : (%?name ?names.%?remark ?remarks)
&  !characters (Character.(name.!name),!remark)
 : ?characters
)
& ("?".xml) (CharacterRemarks.,!characters)
)
& put
$ ( 2XML
$ ( makeList
$ ( April "Tam O'Shanter" Emily
. "Bubbly: I'm > Tam and <= Emily"
"Burns: \"When chapman billies leave the street ...\""
"Short & shrift"
)
)
)
)
Output:
<?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>

C[edit]

Library: libXML
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libxml/parser.h>
#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;
}

C++[edit]

Library: Boost

#include <vector>
#include <utility>
#include <iostream>
#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( "&" , "&amp;" ) ) ;
entities.push_back( std::make_pair( "<" , "&lt;" ) ) ;
entities.push_back( std::make_pair( ">" , "&gt;" ) ) ;
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 ;
}

C#[edit]

Works with: C# version 3.0+
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);
}
}

Clojure[edit]

(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)]}) )})))

Common Lisp[edit]

Library: Closure XML
(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)))

Example of use:

(write-xml '("April" "Tam O'Shanter" "Emily")
'("Bubbly: I'm > Tam and <= Emily"
"Burns: \"When chapman billies leave the street ...\""
"Short & shrift"))
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[edit]

Library: KXML
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);
}
<?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[edit]

 
//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 O''Shanter');
Names.Add('Emily');
 
//Filling the list with remarks
Remarks.Add('Bubbly: I''m > 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;
 
 

Erlang[edit]

 
-module( xml_output ).
 
-export( [task/0] ).
 
-include_lib("xmerl/include/xmerl.hrl").
 
task() ->
Data = {'CharacterRemarks', [], [{'Character', [{name, X}], [[Y]]} || {X, Y} <- contents()]},
lists:flatten( xmerl:export_simple([Data], xmerl_xml) ).
 
 
contents() -> [{"April", "Bubbly: I'm > Tam and <= Emily"}, {"Tam O'Shanter", "Burns: \"When chapman billies leave the street ...\""}, {"Emily", "Short & shrift"}].
 
Output:
4> xml_output:task().                
"<?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>"

Euphoria[edit]

Translation of: BASIC
function xmlquote(sequence s)
sequence r
r = ""
for i = 1 to length(s) do
if s[i] = '<' then
r &= "&lt;"
elsif s[i] = '>' then
r &= "&gt;"
elsif s[i] = '&' then
r &= "&amp;"
elsif s[i] = '"' then
r &= "&quot;"
elsif s[i] = '\'' then
r &= "&apos;"
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")
Output:
<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>

F#[edit]

#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
<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[edit]

USING: sequences xml.syntax xml.writer ;
 
: print-character-remarks ( names remarks -- )
[ [XML <Character name=<-> ><-></Character> XML] ] 2map
[XML <CharacterRemarks><-></CharacterRemarks> XML] pprint-xml ;

Example of usage:

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

Fantom[edit]

 
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)
}
}
 
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[edit]

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

Go[edit]

Using package xml to marshal from a data structure:

package main
 
import (
"encoding/xml"
"fmt"
)
 
// Function required by task description.
func xRemarks(r CharacterRemarks) (string, error) {
b, err := xml.MarshalIndent(r, "", " ")
return string(b), err
}
 
// Task description allows the function to take "a single mapping..."
// This data structure represents a mapping.
type CharacterRemarks struct {
Character []crm
}
 
type crm struct {
Name string `xml:"name,attr"`
Remark string `xml:",chardata"`
}
 
func main() {
x, err := xRemarks(CharacterRemarks{[]crm{
{`April`, `Bubbly: I'm > Tam and <= Emily`},
{`Tam O'Shanter`, `Burns: "When chapman billies leave the street ..."`},
{`Emily`, `Short & shrift`},
}})
if err != nil {
x = err.Error()
}
fmt.Println(x)
}
Output:
<CharacterRemarks>
<Character name="April">Bubbly: I&#39;m &gt; Tam and &lt;= Emily</Character>
<Character name="Tam O&#39;Shanter">Burns: &#34;When chapman billies leave the street ...&#34;</Character>
<Character name="Emily">Short &amp; shrift</Character>
</CharacterRemarks>

Using the text/template package to generate text: (but still leaning on the xml package for escaping.)

package main
 
import (
"bytes"
"encoding/xml"
"fmt"
"text/template"
)
 
type crm struct {
Char, Rem string
}
 
var tmpl = `<CharacterRemarks>
{{range .}} <Character name="{{xml .Char}}">{{xml .Rem}}</Character>
{{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))
 
// Define function required by task description.
xRemarks := func(crms []crm) (string, error) {
var b bytes.Buffer
err := xt.Execute(&b, crms)
return b.String(), err
}
 
// Call the function with example data. The data is represented as
// a "single mapping" as allowed by the task, rather than two lists.
x, err := xRemarks([]crm{
{`April`, `Bubbly: I'm > Tam and <= Emily`},
{`Tam O'Shanter`, `Burns: "When chapman billies leave the street ..."`},
{`Emily`, `Short & shrift`}})
if err != nil {
x = err.Error()
}
fmt.Println(x)
}

Output is same as marshalled version.

Groovy[edit]

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()

Haskell[edit]

This implementation uses the xml package.

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

HicEst[edit]

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='&amp;', DO)
EDIT(Text=remarks, Right='
>', RePLaceby='&gt;', DO)
EDIT(Text=remarks, Right='
<', RePLaceby='&lt;', 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>"

J[edit]

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

tbl=: ('&quote;'; '&amp;'; '&lt;'; '&gt;') (a.i.'"&<>')} <"0 a.
esc=: [:; {&tbl@:i.~&a.

Then create the verb which combines name with remark:

cmb=: [:; dyad define &.>
'<Character name="', (esc x), '">', (esc y), '</Character>', LF
)

Finally, create the verb which creates the final XML:

xmlify=:  '<CharacterRemarks>', LF, cmb, '</CharacterRemarks>'"_

Example:

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

Java[edit]

Using DOM[edit]

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();
}
}
 
}

Result:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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>

Using the Streaming API for XML (StAX)[edit]

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();
}
}
}

This produces:

<?xml version="1.0" encoding="UTF-8"?><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>

Joy[edit]

 
DEFINE subst ==
[[['< "&lt;" putchars]
['> "&gt;" putchars]
['& "&amp;" putchars]
[putch]] case] step;
 
XMLOutput ==
"<CharacterRemarks>\n" putchars
[ "<Character name=\"" putchars uncons swap putchars "\">" putchars first subst "</Character>\n" putchars] step
"</CharacterRemarks>\n" putchars.
 
[ [ "April" "Bubbly: I'm > Tam and <= Emily" ]
[ "Tam O'Shanter" "Burns: \"When chapman billies leave the street ...\"" ]
[ "Emily" "Short & shrift" ]
] XMLOutput.
 


Lasso[edit]

Lasso has built in support for both creating and parsing xml.

define character2xml(names::array, remarks::array) => {
 
fail_if(#names -> size != #remarks -> size, -1, 'Input arrays not of same size')
 
local(
domimpl = xml_domimplementation,
doctype = #domimpl -> createdocumenttype(
'svg:svg',
'-//W3C//DTD SVG 1.1//EN',
'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'
),
character_xml = #domimpl -> createdocument(
'http://www.w3.org/2000/svg',
'svg:svg',
#docType
),
csnode = #character_xml -> createelement('CharacterRemarks'),
charnode
)
 
#character_xml -> appendChild(#csnode)
 
loop(#names -> size) => {
#charnode = #character_xml -> createelement('Character')
#charnode -> setAttribute('name', #names -> get(loop_count))
#charnode -> nodeValue = encode_xml(#remarks -> get(loop_count))
#csnode -> appendChild(#charnode)
}
return #character_xml
 
}
 
character2xml(
array(`April`, `Tam O'Shanter`, `Emily`),
array(`Bubbly: I'm > Tam and <= Emily`, `Burns: "When chapman billies leave the street ..."`, `Short & shrift`)
)
Output:
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg:svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:svg="http://www.w3.org/2000/svg"/>
<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>
 

Lua[edit]

Using the LuaXML library as available via luarocks. Note that strings in Lua can be enclosed in either single or double quotes to help reduce the need for escape characters.

require("LuaXML")
 
function addNode(parent, nodeName, key, value, content)
local node = xml.new(nodeName)
table.insert(node, content)
parent:append(node)[key] = value
end
 
root = xml.new("CharacterRemarks")
addNode(root, "Character", "name", "April", "Bubbly: I'm > Tam and <= Emily")
addNode(root, "Character", "name", "Tam O'Shanter", 'Burns: "When chapman billies leave the street ..."')
addNode(root, "Character", "name", "Emily", "Short & shrift")
print(root)
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>

Note also that LuaXML escapes quote marks and apostrophes, which makes the output slightly different to the task requirement. This can be 'fixed' if necessary using Lua's in-built string.gsub function:

xmlStr = xml.str(root):gsub("&apos;", "'"):gsub("&quot;", '"')
print(xmlStr)
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>

Mathematica[edit]

Some tricky input with the second remark

c = {"April", "Tam O'Shanter","Emily"}; 
r = {"Bubbly:I'm > Tam and <= Emily" ,
StringReplace["Burns:\"When chapman billies leave the street ...\"", "\"" -> ""], "Short & shrift"};
 
ExportString[ XMLElement[ "CharacterRemarks", {},
{XMLElement["Character", {"name" -> c[[1]]}, {r[[1]]}],
XMLElement["Character", {"name" -> c[[2]]}, {r[[2]]}],
XMLElement["Character", {"name" -> c[[3]]}, {r[[3]]}]
}], "XML", "AttributeQuoting" -> "\""]
<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>

NetRexx[edit]

Using DOM[edit]

Translation of: Java
/* 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
 
Output
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<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>
 

Using the Streaming API for XML (StAX)[edit]

Translation of: Java
/* 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
 
Output
<?xml version="1.0" encoding="UTF-8"?>
<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>
 

Nim[edit]

import xmltree, strtabs, sequtils
 
proc charsToXML(names, remarks): XmlNode =
result = <>CharacterRemarks()
for name, remark in items zip(names, remarks):
result.add(<>Character(name=name, remark.newText))
 
echo charsToXML(@["April", "Tam O'Shanter", "Emily"],
@["Bubbly: I'm > Tam and <= Emily",
"Burns: \"When chapman billies leave the street ...\"",
"Short & shrift"])

Output:

<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>

Objeck[edit]

 
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();
}
}
}
 

OCaml[edit]

from the toplevel using the library xml-light:

# #directory "+xml-light" (* or maybe "+site-lib/xml-light" *) ;;
 
# #load "xml-light.cma" ;;
 
# 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&apos;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>
- : unit = ()

Another solution using the library xmlm:

#directory "+xmlm"
#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()

Oz[edit]

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

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 "&lt;"
[] 62 then "&gt;"
[] 38 then "&amp;"
else X
end
end
 
fun {EscapeAttributeChar X}
case X of 34 then "&quot;"
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}

Output:

<?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>

Perl[edit]

Library: XML::MiniMini
#! /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();

Phix[edit]

constant {hchars,hsubs} = columnize({{"<","&lt;"},
{">","&gt;"},
{"&","&amp;"},
{"\"","&quot;"},
{"\'","&apos;"}})
function xmlquote_all(sequence s)
for i=1 to length(s) do
s[i] = substitute_all(s[i],hchars,hsubs)
end for
return s
end function
 
function xml_CharacterRemarks(sequence data)
string res = "<CharacterRemarks>\n"
for i=1 to length(data) do
res &= sprintf(" <CharacterName=\"%s\">%s</Character>\n",xmlquote_all(data[i]))
end for
return res & "</CharacterRemarks>\n"
end function
 
constant testset = {
{"April", "Bubbly: I'm > Tam and <= Emily"},
{"Tam O'Shanter", "Burns: \"When chapman billies leave the street ...\""},
{"Emily", "Short & shrift"}
}
printf(1,xml_CharacterRemarks(testset))
 
-- Sample output:
-- <CharacterRemarks>
-- <CharacterName="April">Bubbly: I&apos;m &amp;gt; Tam and &amp;lt;= Emily</Character>
-- <CharacterName="Tam O&apos;Shanter">Burns: &quot;When chapman billies leave the street ...&quot;</Character>
-- <CharacterName="Emily">Short &amp; shrift</Character>
-- </CharacterRemarks>

PicoLisp[edit]

(load "@lib/xml.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" ) )

Output:

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

PureBasic[edit]

DataSection
dataItemCount:
Data.i 3
 
names:
Data.s "April", "Tam O'Shanter", "Emily"
 
remarks:
Data.s "Bubbly: I'm > Tam and <= Emily",
~"Burns: \"When chapman billies leave the street ...\"",
"Short & shrift"
EndDataSection
 
Structure characteristic
name.s
remark.s
EndStructure
 
NewList didel.characteristic()
Define item.s, numberOfItems, i
 
Restore dataItemCount
Read.i numberOfItems
 
;add names
Restore names
For i = 1 To numberOfItems
AddElement(didel())
Read.s item
didel()\name = item
Next
 
;add remarks
ResetList(didel())
FirstElement(didel())
Restore remarks:
For i = 1 To numberOfItems
Read.s item
didel()\remark = item
NextElement(didel())
Next
 
Define xml, mainNode, itemNode
ResetList(didel())
FirstElement(didel())
xml = CreateXML(#PB_Any)
mainNode = CreateXMLNode(RootXMLNode(xml), "CharacterRemarks")
ForEach didel()
itemNode = CreateXMLNode(mainNode, "Character")
SetXMLAttribute(itemNode, "name", didel()\name)
SetXMLNodeText(itemNode, didel()\remark)
Next
FormatXML(xml, #PB_XML_ReFormat | #PB_XML_WindowsNewline | #PB_XML_ReIndent)
 
If OpenConsole()
PrintN(ComposeXML(xml, #PB_XML_NoDeclaration))
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf

Sample output:

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

Python[edit]

Normal output is all one line of XML, the .replace(...) makes it more readable.

>>> 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<')

Gives the 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>

R[edit]

Library: XML
library(XML)
char2xml <- function(names, remarks){
tt <- xmlHashTree()
head <- addNode(xmlNode("CharacterRemarks"), character(), tt)
node <- list()
for (i in 1:length(names)){
node[[i]] <- addNode(xmlNode("Character", attrs=c(name=names[i])), head, tt)
addNode(xmlTextNode(remarks[i]), node[[i]], 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") )

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>

Racket[edit]

 
#lang racket
(require xml)
 
(define (make-character-xexpr characters remarks)
`(CharacterRemarks
,@(for/list ([character characters]
[remark remarks])
`(Character ((name ,character)) ,remark))))
 
(display-xml/content
(xexpr->xml
(make-character-xexpr
'("April" "Tam O'Shanter" "Emily")
'("Bubbly: I'm > Tam and <= Emily"
"Burns: \"When chapman billies leave the street ...\""
"Short & shrift"))))
 

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>
 

Rascal[edit]

import Prelude;
import lang::xml::DOM;
 
list[str] charnames = ["April", "Tam O\'Shanter", "Emily"];
list[str] remarks = ["Bubbly: I\'m \> Tam and \<= Emily", "Burns: \"When chapman billies leave the street ...\"", "Short & shrift"];
 
public void xmloutput(list[str] n,list[str] r){
if(size(n) != size(r)){
throw "n and r should be of the same size";
}
else{
characters = [element(none(),"Character",[attribute(none(),"name",n[i]), charData(r[i])]),charData("\n")| i <- [0..size(n)-1]];
x = document(element(none(),"CharacterRemarks",characters));
return println(xmlPretty(x));
}
}

This gives an output:

rascal>xmloutput(charnames, remarks)
<?xml version="1.0" encoding="UTF-8"?>
<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>
 
 
ok

REXX[edit]

REXX doesn't have any functions to handle XML entities, an abbreviated version is included here.

/*REXX program creates an  HTML  list of character names  and  remarks. */
charname. =
charname.1 = "April"
charname.2 = "Tam O'Shanter"
charname.3 = "Emily"
do i=1 while charname.i\==''
say 'charname' i '=' charname.i
end /*i*/; say
remark. =
remark.1 = "I'm > Tam and <= Emily"
remark.2 = "When chapman billies leave the street ..."
remark.3 = "Short & shift"
do k=1 while remark.k\==''
say ' remark' k '=' remark.k
end /*k*/; 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 m=1 for create.0
say create.m /*display the Mth entry to term*/
end /*m*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────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 /* & have to be treated special.*/
b=pos(';',x)\==0 /* ; " " " " " */
xml0=0
/* [↓] find a free character ···*/
if a then do /* ··· translate freely·*/
do j=0 to 254;  ?=d2c(j); if pos(?,x)==0 then leave; end
x=translate(x,?,"&"); xml0=j+1
end
/* [↓] find a free character ···*/
if b then do /* ··· 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 */
/*characters in the DOS (or DOS */
/*Windows) codepage 437 */
x=XML_('♥',"hearts")  ; x=XML_('â',"ETH")  ; x=XML_('ƒ',"fnof")  ; x=XML_('═',"boxH")
x=XML_('♦',"diams")  ; x=XML_('â','#x00e2') ; x=XML_('á',"aacute"); x=XML_('╬',"boxVH")
x=XML_('♣',"clubs")  ; x=XML_('â','#x00e9') ; x=XML_('á','#x00e1'); x=XML_('╧',"boxHu")
x=XML_('♠',"spades")  ; x=XML_('ä',"auml")  ; x=XML_('í',"iacute"); x=XML_('╨',"boxhU")
x=XML_('♂',"male")  ; x=XML_('ä','#x00e4') ; x=XML_('í','#x00ed'); x=XML_('╤',"boxHd")
x=XML_('♀',"female")  ; x=XML_('à',"agrave") ; x=XML_('ó',"oacute"); x=XML_('╥',"boxhD")
x=XML_('☼',"#x263c")  ; x=XML_('à','#x00e0') ; x=XML_('ó','#x00f3'); x=XML_('╙',"boxUr")
x=XML_('↕',"UpDownArrow")  ; x=XML_('å',"aring")  ; x=XML_('ú',"uacute"); x=XML_('╘',"boxuR")
x=XML_('¶',"para")  ; x=XML_('å','#x00e5') ; x=XML_('ú','#x00fa'); x=XML_('╒',"boxdR")
x=XML_('§',"sect")  ; x=XML_('ç',"ccedil") ; x=XML_('ñ',"ntilde"); x=XML_('╓',"boxDr")
x=XML_('↑',"uarr")  ; x=XML_('ç','#x00e7') ; x=XML_('ñ','#x00f1'); x=XML_('╫',"boxVh")
x=XML_('↑',"uparrow")  ; x=XML_('ê',"ecirc")  ; x=XML_('Ñ',"Ntilde"); x=XML_('╪',"boxvH")
x=XML_('↑',"ShortUpArrow")  ; x=XML_('ê','#x00ea') ; x=XML_('Ñ','#x00d1'); x=XML_('┘',"boxul")
x=XML_('↓',"darr")  ; x=XML_('ë',"euml")  ; x=XML_('¿',"iquest"); x=XML_('┌',"boxdr")
x=XML_('↓',"downarrow")  ; x=XML_('ë','#x00eb') ; x=XML_('⌐',"bnot")  ; x=XML_('█',"block")
x=XML_('↓',"ShortDownArrow")  ; x=XML_('è',"egrave") ; x=XML_('¬',"not")  ; x=XML_('▄',"lhblk")
x=XML_('←',"larr")  ; x=XML_('è','#x00e8') ; x=XML_('½',"frac12"); x=XML_('▀',"uhblk")
x=XML_('←',"leftarrow")  ; x=XML_('ï',"iuml")  ; x=XML_('½',"half")  ; x=XML_('α',"alpha")
x=XML_('←',"ShortLeftArrow")  ; x=XML_('ï','#x00ef') ; x=XML_('¼',"frac14"); x=XML_('ß',"beta")
x=XML_('1c'x,"rarr")  ; x=XML_('î',"icirc")  ; x=XML_('¡',"iexcl") ; x=XML_('ß',"szlig")
x=XML_('1c'x,"rightarrow")  ; x=XML_('î','#x00ee') ; x=XML_('«',"laqru") ; x=XML_('ß','#x00df')
x=XML_('1c'x,"ShortRightArrow"); x=XML_('ì',"igrave") ; x=XML_('»',"raqru") ; x=XML_('Γ',"Gamma")
x=XML_('!',"excl")  ; x=XML_('ì','#x00ec') ; x=XML_('░',"blk12") ; x=XML_('π',"pi")
x=XML_('"',"apos")  ; x=XML_('Ä',"Auml")  ; x=XML_('▒',"blk14") ; x=XML_('Σ',"Sigma")
x=XML_('$',"dollar")  ; x=XML_('Ä','#x00c4') ; x=XML_('▓',"blk34") ; x=XML_('σ',"sigma")
x=XML_("'","quot")  ; x=XML_('Å',"Aring")  ; x=XML_('│',"boxv")  ; x=XML_('µ',"mu")
x=XML_('*',"ast")  ; x=XML_('Å','#x00c5') ; x=XML_('┤',"boxvl") ; x=XML_('τ',"tau")
x=XML_('/',"sol")  ; x=XML_('É',"Eacute") ; x=XML_('╡',"boxvL") ; x=XML_('Φ',"phi")
x=XML_(':',"colon")  ; x=XML_('É','#x00c9') ; x=XML_('╢',"boxVl") ; x=XML_('Θ',"Theta")
x=XML_('<',"lt")  ; x=XML_('æ',"aelig")  ; x=XML_('╖',"boxDl") ; x=XML_('δ',"delta")
x=XML_('=',"equals")  ; x=XML_('æ','#x00e6') ; x=XML_('╕',"boxdL") ; x=XML_('∞',"infin")
x=XML_('>',"gt")  ; x=XML_('Æ',"AElig")  ; x=XML_('╣',"boxVL") ; x=XML_('φ',"Phi")
x=XML_('?',"quest")  ; x=XML_('Æ','#x00c6') ; x=XML_('║',"boxV")  ; x=XML_('ε',"epsilon")
x=XML_('@',"commat")  ; x=XML_('ô',"ocirc")  ; x=XML_('╗',"boxDL") ; x=XML_('∩',"cap")
x=XML_('[',"lbrack")  ; x=XML_('ô','#x00f4') ; x=XML_('╝',"boxUL") ; x=XML_('≡',"equiv")
x=XML_('\',"bsol")  ; x=XML_('ö',"ouml")  ; x=XML_('╜',"boxUl") ; x=XML_('±',"plusmn")
x=XML_(']',"rbrack")  ; x=XML_('ö','#x00f6') ; x=XML_('╛',"boxuL") ; x=XML_('±',"pm")
x=XML_('^',"Hat")  ; x=XML_('ò',"ograve") ; x=XML_('┐',"boxdl") ; x=XML_('±',"PlusMinus")
x=XML_('`',"grave")  ; x=XML_('ò','#x00f2') ; x=XML_('└',"boxur") ; x=XML_('≥',"ge")
x=XML_('{',"lbrace")  ; x=XML_('û',"ucirc")  ; x=XML_('┴',"bottom"); x=XML_('≤',"le")
x=XML_('{',"lcub")  ; x=XML_('û','#x00fb') ; x=XML_('┴',"boxhu") ; x=XML_('÷',"div")
x=XML_('|',"vert")  ; x=XML_('ù',"ugrave") ; x=XML_('┬',"boxhd") ; x=XML_('÷',"divide")
x=XML_('|',"verbar")  ; x=XML_('ù','#x00f9') ; x=XML_('├',"boxvr") ; x=XML_('≈',"approx")
x=XML_('}',"rbrace")  ; x=XML_('ÿ',"yuml")  ; x=XML_('─',"boxh")  ; x=XML_('∙',"bull")
x=XML_('}',"rcub")  ; x=XML_('ÿ','#x00ff') ; x=XML_('┼',"boxvh") ; x=XML_('°',"deg")
x=XML_('Ç',"Ccedil")  ; x=XML_('Ö',"Ouml")  ; x=XML_('╞',"boxvR") ; x=XML_('·',"middot")
x=XML_('Ç','#x00c7')  ; x=XML_('Ö','#x00d6') ; x=XML_('╟',"boxVr") ; x=XML_('·',"middledot")
x=XML_('ü',"uuml")  ; x=XML_('Ü',"Uuml")  ; x=XML_('╚',"boxUR") ; x=XML_('·',"centerdot")
x=XML_('ü','#x00fc')  ; x=XML_('Ü','#x00dc') ; x=XML_('╔',"boxDR") ; x=XML_('·',"CenterDot")
x=XML_('é',"eacute")  ; x=XML_('¢',"cent")  ; x=XML_('╩',"boxHU") ; x=XML_('√',"radic")
x=XML_('é','#x00e9')  ; x=XML_('£',"pound")  ; x=XML_('╦',"boxHD") ; x=XML_('²',"sup2")
x=XML_('â',"acirc")  ; x=XML_('¥',"yen")  ; x=XML_('╠',"boxVR") ; x=XML_('■',"squart ")
 
if a then x=xml_(?,"amp") /*if there was an ampersand, translate it*/
if b then x=xml_(??,"semi") /* " " " " semicolon, " "*/
return x

Some older REXXes don't have a changestr bif, so one is included here ──► CHANGESTR.REX.

output   (unrendered):

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 <&equals; Emily"</Character>
    <Character name="Tam O"Shanter">"When chapman billies leave the street ..."</Character>
    <Character name="Emily">"Short & shift"</Character>
</CharacterRemarks>

Ruby[edit]

The
Library: REXML
library handles character mapping when adding attributes and text.
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
 
# output with indentation
doc.write($stdout, 2)

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[edit]

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)
 

Result:

<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>

Sidef[edit]

Translation of: Perl
require('XML::Mini::Document');
 
var students = [
["April", "Bubbly: I'm > Tam and <= Emily"],
["Tam O'Shanter", "Burns: \"When chapman billies leave the street ...\""],
["Emily", "Short & shrift"]
];
 
var doc = %s'XML::Mini::Document'.new;
var root = doc.getRoot;
var studs = root.createChild("CharacterRemarks");
 
students.each { |s|
var stud = studs.createChild("Character");
stud.attribute("name", s[0]);
stud.text(s[1]);
};
 
print doc.toString;

Slate[edit]

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

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[edit]

Using only Tcl string manipulation[edit]

proc xquote string {
list [string map "' &apos; \\\" &quot; < &gt; > &lt; & &amp;" $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]
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[edit]

Using
Library: tDOM
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
<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
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

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[edit]

 
$$ MODE TUSCRIPT
STRUCTURE xmloutput
DATA '<CharacterRemarks>'
DATA * ' <Character name="' names +'">' remarks +'</Character>'
DATA = '</CharacterRemarks>'
ENDSTRUCTURE
BUILD X_TABLE entitysubst=" >> &gt; << &lt; & &amp; "
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
 

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>  

VBScript[edit]

Saves in a file.

 
Set objXMLDoc = CreateObject("msxml2.domdocument")
 
Set objRoot = objXMLDoc.createElement("CharacterRemarks")
objXMLDoc.appendChild objRoot
 
Call CreateNode("April","Bubbly: I'm > Tam and <= Emily")
Call CreateNode("Tam O'Shanter","Burns: ""When chapman billies leave the street ...""")
Call CreateNode("Emily","Short & shrift")
 
objXMLDoc.save("C:\Temp\Test.xml")
 
Function CreateNode(attrib_value,node_value)
Set objNode = objXMLDoc.createElement("Character")
objNode.setAttribute "name", attrib_value
objNode.text = node_value
objRoot.appendChild objNode
End Function
 

Vedit macro language[edit]

The input data is given in an edit buffer, one name+remark pair on each line line, separated with TAB character.

// Replace special characters with entities:
Replace("&", "&amp;", BEGIN+ALL+NOERR) // this must be the first replace!
Replace("<", "&lt;", BEGIN+ALL+NOERR)
Replace(">", "&gt;", BEGIN+ALL+NOERR)
Replace("'", "&apos;", BEGIN+ALL+NOERR)
Replace('"', "&quot;", 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

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[edit]

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

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>

XPL0[edit]

code ChOut=8, CrLf=9, Text=12;
string 0; \use zero-terminated strings
 
proc XmlOut(S); \Output string in XML format
char S;
repeat case S(0) of \character entity substitutions
^<: Text(0, "&lt;");
^>: Text(0, "&gt;");
^&: Text(0, "&amp;");
^": Text(0, "&quot;");
^': Text(0, "&apos;")
other ChOut(0, S(0));
S:= S+1;
until S(0) = 0;
 
int Name, Remark, I;
[Name:= ["April", "Tam O'Shanter", "Emily"];
Remark:= ["Bubbly: I'm > Tam and <= Emily",
"Burns: ^"When chapman billies leave the street ...^"",
"Short & shrift"];
Text(0, "<CharacterRemarks>"); CrLf(0);
for I:= 0 to 3-1 do
[Text(0, " <Character name=^"");
XmlOut(Name(I));
Text(0, "^">");
XmlOut(Remark(I));
Text(0, "</Character>"); CrLf(0);
];
Text(0, "</CharacterRemarks>"); CrLf(0);
]
Output:
<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>

zkl[edit]

fcn xmlEscape(text){
text.replace(" &"," &amp;") .replace(" \""," &quot;")
.replace(" '"," &apos;") .replace(" <"," &lt;") .replace(" >"," &gt;")
}
fcn toXML(as,bs){
xml:=Sink("<CharacterRemarks>\n");
as.zipWith('wrap(a,b){
xml.write(" <Character name=\"",xmlEscape(a),"\">",
xmlEscape(b),"</Character>\n");
},bs);
xml.write("</CharacterRemarks>\n").close();
}
 
toXML(T("April", "Tam O'Shanter", "Emily"),
T("Bubbly: I'm > Tam and <= Emily",
0'|Burns: "When chapman billies leave the street ..."|,
"Short & shrift"))
.print();
Output:
<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>