XML/Output

From Rosetta Code

< XML(Redirected from XML Creation)
Jump to: navigation, search
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.

Contents

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

[edit] BASIC

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

[edit] C

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

[edit] C++

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

[edit] C#

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

[edit] Clojure

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

[edit] Common Lisp

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>

[edit] D

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>

[edit] F#

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

[edit] Factor

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

[edit] Haskell

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

[edit] 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='&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>"

[edit] J

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>

[edit] Java

[edit] Using DOM

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>

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

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>

[edit] OCaml

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

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

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>

[edit] Perl

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

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

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>

[edit] PureBasic

input lines are in separate files names.txt and remarks.txt. Output-XML is written to file demo.xml .

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

[edit] Python

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>

[edit] R

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

[edit] Ruby

The Library: REXMLlibrary 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>

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

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>

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

Produces:

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

[edit] Tcl

[edit] Using only Tcl string manipulation

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>

[edit] Working with DOM trees

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>

[edit] Vedit macro language

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>

[edit] Visual Basic .NET

This example may be incorrect due to a recent change in the task requirements or a lack of testing. Please verify it and remove this message. If the example does not match the requirements or does not work, replace this message with Template:incorrect or fix the code yourself.
Dim names As String() = New String() {"April", "Bob", "Chad", "Dave", "Emily"}
 
Dim xml = <Students>
<%= From s In names Select <Student Name=<%= s %>/> %>
</Students>
Console.WriteLine(xml)
Personal tools
Support