-
-
Notifications
You must be signed in to change notification settings - Fork 110
Conversion From Object
Child nodes can also be created by passing an object to the element
or create
functions. Here is an example:
var obj = {
person: {
name: "John",
'@age': 35,
address: {
city: "Istanbul"
},
'#list': [
{ phone: { '#text': "555-1234", '@type': 'home' } },
{ phone: { '#text': "555-1235", '@type': 'mobile' } }
],
id: function() {
return 42;
}
}
};
var builder = require('xmlbuilder');
var root = builder.create(obj);
The resulting XML will be:
<?xml version="1.0"?>
<person age="35">
<name>John</name>
<address>
<city>Istanbul</city>
</address>
<phone type="home">555-1234</phone>
<phone type="mobile">555-1235</phone>
<id>42</id>
</person>
Objects will be expanded recursively and each name-value pair is converted to an XML node.
root.ele({
person: {
name: "John"
}
});
<person>
<name>John</name>
</person>
Arrays will also be expanded and each array item is converted to an XML node.
root.ele({
numbers: [
"one",
"two",
three: { "@val": 3 }
]
});
<numbers>
<one/>
<two/>
<three val="3"/>
</numbers>
If a function is passed as an object value, it will be evaluated and its return value will be the node value.
root.ele({
row: {
id: function() { return 42; }
}
});
<row>
<id>42</id>
</row>
Functions can return objects and array which will be passed recursively to the element
function to create child nodes.
root.ele({
squares: function() {
var results = [];
for (var i = 1; i <= 5; i++) {
results.push({ data: { '@x': i, '@y': i * i } });
}
return results;
}
});
<squares>
<data x="1" y="1"/>
<data x="2" y="4"/>
<data x="3" y="9"/>
<data x="4" y="16"/>
<data x="5" y="25"/>
</squares>
XML attributes and special nodes are recognized with decorator strings. For example, if an object name starts with @
, it will be converted to an XML attribute. Decorators can be customized while calling the create
method. Default decorators are shown below.
var root = xmlbuilder.create(obj, {
stringify: {
convertAttKey: '@',
convertPIKey: '!',
convertTextKey: '#text',
convertCDataKey: '#cdata',
convertCommentKey: '#comment',
convertRawKey: '#raw',
convertListKey: '#list'
}
});
Attribute decorator (default @
) marks its name-value pair as an attribute. Those attributes are collected and applied to the parent node.
root.ele({
person: {
name: "John",
"@age": 35
}
});
<person age="35">
<name>John</name>
</person>
Processing instruction decorator (default ?
) marks its name-value pair as an XML processing instruction. Those instructions are collected and applied to the parent node.
root.ele({
person: {
name: "John",
"!target": "content"
}
});
<?target content?>
<person>
<name>John</name>
</person>
Text decorator (default #text
) marks its value as a text node.
root.ele({
person: {
name: "John",
"#text": "Smith"
}
});
<person>
<name>John</name>
Smith
</person>
CData decorator (default #cdata
) marks its value as a CData node.
root.ele({
person: {
name: "John",
"#cdata": "Smith"
}
});
<person>
<name>John</name>
<![CDATA[Smith]]>
</person>
Comment decorator (default #comment
) marks its value as a comment node.
root.ele({
person: {
name: "John",
"#comment": "Smith"
}
});
<person>
<name>John</name>
<!-- Smith -->
</person>
Raw decorator (default #raw
) marks its value as a text node, but its contents will not be escaped.
root.ele({
person: {
name: "John",
"#raw": "&<>&"
}
});
<person>
<name>John</name>
&<>&
</person>
List decorator (default #list
) marks its value as a list of nodes. In this case, a parent node will not be created; list items will be appended to the immediate parent node.
root.ele({
person: {
name: "John",
'#list': [
{ phone: "555-1234" },
{ phone: "555-1235" }
]
}
});
<person>
<name>John</name>
<phone>555-1234</phone>
<phone>555-1235</phone>
</person>