org.hisrc.jsonix.Jsonix.XML.Output.js Maven / Gradle / Ivy
Jsonix.XML.Output = Jsonix.Class({
document : null,
documentElement : null,
node : null,
nodes : null,
nsp : null,
pns : null,
namespacePrefixIndex : 0,
xmldom : null,
initialize : function(options) {
// REWORK
if (typeof ActiveXObject !== 'undefined') {
this.xmldom = new ActiveXObject("Microsoft.XMLDOM");
} else {
this.xmldom = null;
}
this.nodes = [];
var rootNspItem =
{
'' : ''
};
rootNspItem[Jsonix.XML.XMLNS_NS] = Jsonix.XML.XMLNS_P;
if (Jsonix.Util.Type.isObject(options)) {
if (Jsonix.Util.Type.isObject(options.namespacePrefixes)) {
Jsonix.Util.Type.cloneObject(options.namespacePrefixes, rootNspItem);
}
}
this.nsp = [rootNspItem];
var rootPnsItem =
{
'' : ''
};
rootPnsItem[Jsonix.XML.XMLNS_P] = Jsonix.XML.XMLNS_NS;
this.pns = [rootPnsItem];
},
destroy : function() {
this.xmldom = null;
},
writeStartDocument : function() {
// TODO Check
var doc = Jsonix.DOM.createDocument();
this.document = doc;
return this.push(doc);
},
writeEndDocument : function() {
return this.pop();
},
writeStartElement : function(name) {
Jsonix.Util.Ensure.ensureObject(name);
var localPart = name.localPart || name.lp || null;
Jsonix.Util.Ensure.ensureString(localPart);
var ns = name.namespaceURI || name.ns || null;
var namespaceURI = Jsonix.Util.Type.isString(ns) ? ns : '';
var p = name.prefix || name.p;
var prefix = this.getPrefix(namespaceURI, p);
var qualifiedName = (!prefix ? localPart : prefix + ':' + localPart);
var element;
if (Jsonix.Util.Type.isFunction(this.document.createElementNS)) {
element = this.document.createElementNS(namespaceURI, qualifiedName);
}
else if (this.xmldom) {
element = this.xmldom.createNode(1, qualifiedName, namespaceURI);
} else {
throw new Error("Could not create an element node.");
}
this.peek().appendChild(element);
this.push(element);
this.declareNamespace(namespaceURI, prefix);
if (this.documentElement === null)
{
this.documentElement = element;
this.declareNamespaces();
}
return element;
},
writeEndElement : function() {
return this.pop();
},
writeCharacters : function(text) {
var node;
if (Jsonix.Util.Type.isFunction(this.document.createTextNode)) {
node = this.document.createTextNode(text);
}
else if (this.xmldom) {
node = this.xmldom.createTextNode(text);
} else {
throw new Error("Could not create a text node.");
}
this.peek().appendChild(node);
return node;
},
writeAttribute : function(name, value) {
Jsonix.Util.Ensure.ensureString(value);
Jsonix.Util.Ensure.ensureObject(name);
var localPart = name.localPart || name.lp || null;
Jsonix.Util.Ensure.ensureString(localPart);
var ns = name.namespaceURI || name.ns || null;
var namespaceURI = Jsonix.Util.Type.isString(ns) ? ns : '';
var p = name.prefix || name.p || null;
var prefix = this.getPrefix(namespaceURI, p);
var qualifiedName = (!prefix ? localPart : prefix + ':' + localPart);
var node = this.peek();
if (namespaceURI === '') {
node.setAttribute(qualifiedName, value);
} else {
if (node.setAttributeNS) {
node.setAttributeNS(namespaceURI, qualifiedName, value);
} else {
if (this.xmldom) {
var attribute = this.document.createNode(2, qualifiedName, namespaceURI);
attribute.nodeValue = value;
node.setAttributeNode(attribute);
}
else if (namespaceURI === Jsonix.XML.XMLNS_NS)
{
// XMLNS namespace may be processed unqualified
node.setAttribute(qualifiedName, value);
}
else
{
throw new Error("The [setAttributeNS] method is not implemented");
}
}
this.declareNamespace(namespaceURI, prefix);
}
},
writeNode : function(node) {
var importedNode;
if (Jsonix.Util.Type.exists(this.document.importNode)) {
importedNode = this.document.importNode(node, true);
} else {
importedNode = node;
}
this.peek().appendChild(importedNode);
return importedNode;
},
push : function(node) {
this.nodes.push(node);
this.pushNS();
return node;
},
peek : function() {
return this.nodes[this.nodes.length - 1];
},
pop : function() {
this.popNS();
var result = this.nodes.pop();
return result;
},
pushNS : function ()
{
var nindex = this.nsp.length - 1;
var pindex = this.pns.length - 1;
var parentNspItem = this.nsp[nindex];
var parentPnsItem = this.pns[pindex];
var nspItem = Jsonix.Util.Type.isObject(parentNspItem) ? nindex : parentNspItem;
var pnsItem = Jsonix.Util.Type.isObject(parentPnsItem) ? pindex : parentPnsItem;
this.nsp.push(nspItem);
this.pns.push(pnsItem);
},
popNS : function ()
{
this.nsp.pop();
this.pns.pop();
},
declareNamespaces : function ()
{
var index = this.nsp.length - 1;
var nspItem = this.nsp[index];
nspItem = Jsonix.Util.Type.isNumber(nspItem) ? this.nsp[nspItem] : nspItem;
var ns, p;
for (ns in nspItem)
{
if (nspItem.hasOwnProperty(ns))
{
p = nspItem[ns];
this.declareNamespace(ns, p);
}
}
},
declareNamespace : function (ns, p)
{
var index = this.pns.length - 1;
var pnsItem = this.pns[index];
var reference;
if (Jsonix.Util.Type.isNumber(pnsItem))
{
// Resolve the reference
reference = true;
pnsItem = this.pns[pnsItem];
}
else
{
reference = false;
}
// If this prefix is mapped to a different namespace and must be redeclared
if (pnsItem[p] !== ns)
{
if (p === '')
{
this.writeAttribute({lp : Jsonix.XML.XMLNS_P}, ns);
}
else
{
this.writeAttribute({ns : Jsonix.XML.XMLNS_NS, lp : p, p : Jsonix.XML.XMLNS_P}, ns);
}
if (reference)
{
// If this was a reference, clone it and replace the reference
pnsItem = Jsonix.Util.Type.cloneObject(pnsItem, {});
this.pns[index] = pnsItem;
}
pnsItem[p] = ns;
}
},
getPrefix : function (ns, p)
{
var index = this.nsp.length - 1;
var nspItem = this.nsp[index];
var reference;
if (Jsonix.Util.Type.isNumber(nspItem))
{
// This is a reference, the item is the index of the parent item
reference = true;
nspItem = this.nsp[nspItem];
}
else
{
reference = false;
}
if (Jsonix.Util.Type.isString(p))
{
var oldp = nspItem[ns];
// If prefix is already declared and equals the proposed prefix
if (p === oldp)
{
// Nothing to do
}
else
{
// If this was a reference, we have to clone it now
if (reference)
{
nspItem = Jsonix.Util.Type.cloneObject(nspItem, {});
this.nsp[index] = nspItem;
}
nspItem[ns] = p;
}
}
else
{
p = nspItem[ns];
if (!Jsonix.Util.Type.exists(p)) {
p = 'p' + (this.namespacePrefixIndex++);
// If this was a reference, we have to clone it now
if (reference)
{
nspItem = Jsonix.Util.Type.cloneObject(nspItem, {});
this.nsp[index] = nspItem;
}
nspItem[ns] = p;
}
}
return p;
},
getNamespaceURI : function (p) {
var pindex = this.pns.length - 1;
var pnsItem = this.pns[pindex];
pnsItem = Jsonix.Util.Type.isObject(pnsItem) ? pnsItem : this.pns[pnsItem];
return pnsItem[p];
},
CLASS_NAME : "Jsonix.XML.Output"
});
© 2015 - 2024 Weber Informatics LLC | Privacy Policy