XML/DOM serialization

From Rosetta Code

< XML
Jump to: navigation, search
Task
XML/DOM serialization
You are encouraged to solve this task according to the task description, using any language you may know.

Create a simple DOM and having it serialize to:

 <?xml version="1.0" ?>
 <root>
     <element>
         Some text here
     </element>
 </root>

Contents

[edit] AutoHotkey

version = "1.0"
xmlheader := "<?xml version=" . version . "?>" . "<" . root . ">"
 
element("root", "child")
element("root", "element", "more text here")
element("root_child", "kid", "yak yak")
MsgBox % xmlheader . serialize("root")
Return
 
element(parent, name, text="")
{
Global
%parent%_children .= name . "`n"
%parent%_%name% = %parent%_%name%
%parent%_%name%_name := name
%parent%_%name%_text := text
}
 
serialize(root){
StringSplit, root, root, _
xml .= "<" . root%root0% . ">"
StringTrimRight, %root%_children, %root%_children, 1
Loop, Parse, %root%_children, `n
{
If %root%_%A_LoopField%_children
xml .= serialize(%root%_%A_LoopField%)
Else
{
element := "<" . %root%_%A_LoopField%_name . ">"
element .= %root%_%A_LoopField%_text
element .= "</" . %root%_%A_LoopField%_name . ">"
xml .= element
}
}
Return xml .= "</" . root%root0% . ">"
}

[edit] C

Library: libxml

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
 
int main()
{
const char **next;
int a;
FILE *outFile;
 
xmlDoc *doc = xmlNewDoc("1.0");
xmlNode *root = xmlNewNode(NULL, "root");
xmlDocSetRootElement(doc, root);
 
xmlNode *node = xmlNewNode(NULL, "element");
xmlAddChild(node, xmlNewText("some text here"));
xmlAddChild(root, node);
 
outFile = fopen("myfile.xml", "w");
xmlElemDump(outFile, doc, root);
fclose(outFile);
 
xmlFreeDoc(doc);
xmlCleanupParser();
 
return EXIT_SUCCESS;
}

[edit] C#

Serialization using the built-in System.Xml.Serialization library of .Net.

using System.Xml;
using System.Xml.Serialization;
[XmlRoot("root")]
public class ExampleXML
{
[XmlElement("element")]
public string element = "Some text here";
static void Main(string[] args)
{
var xmlnamespace = new XmlSerializerNamespaces();
xmlnamespace.Add("", ""); //used to stop default namespaces from printing
var writer = XmlWriter.Create("output.xml");
new XmlSerializer(typeof(ExampleXML)).Serialize(writer, new ExampleXML(), xmlnamespace);
}
//Output: <?xml version="1.0" encoding="utf-8"?><root><element>Some text here</element></root>
}

[edit] Common Lisp

Library: Closure XML

Assuming that matching the whitespace in the problem description isn't necessary and that character encodings are permitted (see the talk page):

(let* ((doc (dom:create-document 'rune-dom:implementation nil nil nil))
(root (dom:create-element doc "root"))
(element (dom:create-element doc "element"))
(text (dom:create-text-node doc "Some text here")))
(dom:append-child element text)
(dom:append-child root element)
(dom:append-child doc root)
(dom:map-document (cxml:make-rod-sink) doc))

gives the following output:

<?xml version="1.0" encoding="UTF-8"?>
<root><element>Some text here</element></root>

Because dom:append-child returns the appended child, the same output can be produced while binding fewer variables:

(let ((doc (dom:create-document 'rune-dom:implementation nil nil nil)))
(dom:append-child
(dom:append-child
(dom:append-child doc (dom:create-element doc "root"))
(dom:create-element doc "element"))
(dom:create-text-node doc "Some text here"))
(write-string (dom:map-document (cxml:make-rod-sink) doc)))

The prefix notation makes this hard to decipher, however, and so a final version uses an auxiliary append-child*:

(defun append-child* (parent &rest children)
(reduce 'dom:append-child children :initial-value parent))
 
(let* ((doc (dom:create-document 'rune-dom:implementation nil nil nil)))
(append-child* doc
(dom:create-element doc "root")
(dom:create-element doc "element")
(dom:create-text-node doc "Some text here"))
(write-string (dom:map-document (cxml:make-rod-sink) doc)))

[edit] D

Works with: D version 2.011+

module xmltest ;
 
import std.stdio ;
import std.xml ;
 
void main() {
auto doc = new Document("root") ;
//doc.prolog = q"/<?xml version="1.0"?>/" ; // default
doc ~= new Element("element", "Some text here") ;
writefln(doc) ;
// output: <?xml version="1.0"?><root><element>Some text here</element></root>
}

[edit] E

Works with: E-on-Java This makes use of XML libraries provided with Java.

def document := <unsafe:javax.xml.parsers.makeDocumentBuilderFactory> \
.newInstance() \
.newDocumentBuilder() \
.getDOMImplementation() \
.createDocument(null, "root", null)
def root := document.getDocumentElement()
root.appendChild(
def element := document.createElement("element"))
element.appendChild(
document.createTextNode("Some text here"))
println(document.saveXML(root))

(On the use of <unsafe>: The class has not yet been reviewed for E safety, so <import:...makeDocumentBuilderFactory> is not yet allowed. The review would probably be straightforward.)

[edit] Forth

Library: Forth Foundation Library

include ffl/dom.fs
 
\ Create a dom variable 'doc' in the dictionary
 
dom-create doc
 
\ Add the document root with its version attribute
 
dom.document doc dom-append-node
 
s" version" s" 1.0" dom.attribute doc dom-append-node
 
\ Add root and element
 
doc dom-parent 2drop
 
s" root" dom.element doc dom-append-node
 
s" element" dom.element doc dom-append-node
 
\ Add the text
 
s" Some text here" dom.text doc dom-append-node
 
\ Convert the document to a string and print
 
doc dom-write-string [IF]
type cr
[THEN]

[edit] Groovy

import groovy.xml.MarkupBuilder
def writer = new StringWriter() << '<?xml version="1.0" ?>\n'
def xml = new MarkupBuilder(writer)
xml.root() {
element('Some text here' )
}
println writer

[edit] Haskell

Using the XML.Light module from HackageDB

import Data.List
import Text.XML.Light
 
xmlDOM :: String -> String
xmlDOM txt = showTopElement $ Element
(unqual "root")
[]
[ Elem $ Element
(unqual "element")
[]
[Text $ CData CDataText txt Nothing]
Nothing
]
Nothing

Output:

*Main> mapM_ (putStrLn.ppContent) $ parseXML (xmlDOM "  Some text  ")
<?xml version="1.0" ?>
<root>
  <element>  Some text  </element>
</root>

[edit] JavaScript

Works with: Firefox version 2.0 DOM

var doc = document.implementation.createDocument( null, 'root', null );
var root = doc.documentElement;
var element = doc.createElement( 'element' );
root.appendChild( element );
element.appendChild( document.createTextNode('Some text here') );
var xmlString = new XMLSerializer().serializeToString( doc );

E4X

var xml = <root>
<element>Some text here</element>
</root>;
var xmlString = xml.toXMLString();

E4X — with processing instruction

XML.ignoreProcessingInstructions = false;
var xml = <?xml version="1.0"?>
<root>
<element>Some text here</element>
</root>;
var xmlString = xml.toXMLString();

[edit] Oz

With the code from XML Creation#Oz, we can write:

declare
proc {Main}
DOM = root(element("Some text here"))
in
{System.showInfo {Serialize DOM}}
end
...

Output:

<?xml version="1.0" ?>
<root>
<element>Some text here</element>
</root>

[edit] Perl

Library: XML::SimpleSimple

use XML::Simple;
print XMLout( { root => { element => "Some text here" } }, NoAttr => 1, RootName => "" );

Output:

<root>
  <element>Some text here</element>
</root>

Library: XML::DOM::BagOfTricksBagOfTricks

use XML::DOM::BagOfTricks qw(createDocument createTextElement);
 
my ($doc, $root) = createDocument('root');
$root->appendChild(
createTextElement($doc, 'element', 'Some text here')
);
print $doc->toString;

Output:

<root><element>Some text here</element></root>

Library: LibXML

use XML::LibXML;
 
$xml = XML::LibXML::Document->new('1.0');
$node = $xml->createElement('root');
$xml->setDocumentElement($node);
$node2 = $xml->createElement('element');
$text = $xml->createTextNode('Some text here');
$node2->addChild($text);
$node->appendWellBalancedChunk('text');
$node->addChild($node2);
 
print $xml->toString;

Output:

<?xml version="1.0"?>
<root>text<element>Some text here</element></root>

[edit] PHP

Works with: PHP version 5

<?php
$dom = new DOMDocument();//the constructor also takes the version and char-encoding as it's two respective parameters
$dom->formatOutput = true;//format the outputted xml
$root = $dom->createElement('root');
$element = $dom->createElement('element');
$element->appendChild($dom->createTextNode('Some text here'));
$root->appendChild($element);
$dom->appendChild($root);
$xmlstring = $dom->saveXML();

[edit] PicoLisp

(load "@lib/xm.l")
 
(xml? T)
(xml '(root NIL (element NIL "Some text here")))

Output:

<?xml version="1.0" encoding="utf-8"?>
<root>
   <element>Some text here</element>
</root>

[edit] Python

Works with: Python version 2.5

from xml.dom.minidom import getDOMImplementation
 
dom = getDOMImplementation()
document = dom.createDocument(None, "root", None)
 
topElement = document.documentElement
firstElement = document.createElement("element")
topElement.appendChild(firstElement)
textNode = document.createTextNode("Some text here")
firstElement.appendChild(textNode)
 
xmlString = document.toprettyxml(" " * 4)
from xml.etree import ElementTree as et
 
root = et.Element("root")
et.SubElement(root, "element").text = "Some text here"
xmlString = et.tostring(root)

[edit] Ruby

Library: REXML

require("rexml/document")
include REXML
(doc = Document.new) << XMLDecl.new
root = doc.add_element('root')
element = root.add_element('element')
element.add_text('Some text here')
 
# save to a string
# (the first argument to write() needs an object that understands "<<")
serialized = String.new
doc.write(serialized, 4)
puts serialized

produces

<?xml version='1.0'?>
<root>
    <element>
        Some text here
    </element>
</root>

[edit] Scala

val xml = <root><element>Some text here</element></root>
scala.xml.XML.save(filename="output.xml", node=xml, enc="UTF-8", xmlDecl=true, doctype=null)

[edit] Tcl

Library: tDOM

package require tdom
set d [dom createDocument root]
set root [$d documentElement]
$root appendChild [$d createElement element]
[$root firstChild] appendChild [$d createTextNode "Some text here"]
$d asXML
<root>
    <element>Some text here</element>
</root>

Using TclDOM

package require dom
set doc [dom::DOMImplementation create]
set root [dom::document createElement $doc root]
set elem [dom::document createElement $root element]
set text [dom::document createTextNode $elem "Some text here"]
dom::DOMImplementation serialize $doc -newline {element}
<?xml version='1.0'?>
<!DOCTYPE root>
<root>
<element>
Some text here
</element>
</root>

[edit] XQuery

In XQuery static element construction is like normal XML:

<root>
<element>
Some text here
</element>
</root>

Dynamic element construction looks quite different:

let $rootTagname := 'root'
let $elementTagname := 'element'
let $elementContent := 'Some text here'
 
return
element {$rootTagname}
{
element{$elementTagname}
{$elementContent}
}

[edit] XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/"> <!-- replace the root of the incoming document with our own model -->
<xsl:element name="root">
<xsl:element name="element">
<xsl:text>Some text here</xsl:text>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Personal tools
Support