org.hisrc.jsonix.Jsonix.XML.Input.js Maven / Gradle / Ivy
Jsonix.XML.Input = Jsonix.Class({
root : null,
node : null,
attributes : null,
eventType : null,
pns : null,
initialize : function(node) {
Jsonix.Util.Ensure.ensureExists(node);
this.root = node;
var rootPnsItem =
{
'' : ''
};
rootPnsItem[Jsonix.XML.XMLNS_P] = Jsonix.XML.XMLNS_NS;
this.pns = [rootPnsItem];
},
hasNext : function() {
// No current node, we've not started yet
if (this.node === null) {
return true;
} else if (this.node === this.root) {
var nodeType = this.node.nodeType;
// Root node is document, last event type is END_DOCUMENT
if (nodeType === 9 && this.eventType === 8) {
return false;
}
// Root node is element, last event type is END_ELEMENT
else if (nodeType === 1 && this.eventType === 2) {
return false;
} else {
return true;
}
} else {
return true;
}
},
next : function() {
if (this.eventType === null) {
return this.enter(this.root);
}
// START_DOCUMENT
if (this.eventType === 7) {
var documentElement = this.node.documentElement;
if (documentElement) {
return this.enter(documentElement);
} else {
return this.leave(this.node);
}
} else if (this.eventType === 1) {
var firstChild = this.node.firstChild;
if (firstChild) {
return this.enter(firstChild);
} else {
return this.leave(this.node);
}
} else if (this.eventType === 2) {
var nextSibling = this.node.nextSibling;
if (nextSibling) {
return this.enter(nextSibling);
} else {
return this.leave(this.node);
}
} else {
return this.leave(this.node);
}
},
enter : function(node) {
var nodeType = node.nodeType;
this.node = node;
this.attributes = null;
// Document node
if (nodeType === 1) {
// START_ELEMENT
this.eventType = 1;
this.pushNS(node);
return this.eventType;
} else if (nodeType === 2) {
// ATTRIBUTE
this.eventType = 10;
return this.eventType;
} else if (nodeType === 3) {
var nodeValue = node.nodeValue;
if (Jsonix.Util.StringUtils.isEmpty(nodeValue)) {
// SPACE
this.eventType = 6;
} else {
// CHARACTERS
this.eventType = 4;
}
return this.eventType;
} else if (nodeType === 4) {
// CDATA
this.eventType = 12;
return this.eventType;
} else if (nodeType === 5) {
// ENTITY_REFERENCE_NODE = 5
// ENTITY_REFERENCE
this.eventType = 9;
return this.eventType;
} else if (nodeType === 6) {
// ENTITY_DECLARATION
this.eventType = 15;
return this.eventType;
} else if (nodeType === 7) {
// PROCESSING_INSTRUCTION
this.eventType = 3;
return this.eventType;
} else if (nodeType === 8) {
// COMMENT
this.eventType = 5;
return this.eventType;
} else if (nodeType === 9) {
// START_DOCUMENT
this.eventType = 7;
return this.eventType;
} else if (nodeType === 10) {
// DTD
this.eventType = 12;
return this.eventType;
} else if (nodeType === 12) {
// NOTATION_DECLARATION
this.eventType = 14;
return this.eventType;
} else {
// DOCUMENT_FRAGMENT_NODE = 11
throw new Error("Node type [" + nodeType + '] is not supported.');
}
},
leave : function(node) {
if (node.nodeType === 9) {
if (this.eventType == 8) {
throw new Error("Invalid state.");
} else {
this.node = node;
this.attributes = null;
// END_ELEMENT
this.eventType = 8;
return this.eventType;
}
} else if (node.nodeType === 1) {
if (this.eventType == 2) {
var nextSibling = node.nextSibling;
if (nextSibling) {
return this.enter(nextSibling);
}
} else {
this.node = node;
this.attributes = null;
// END_ELEMENT
this.eventType = 2;
this.popNS();
return this.eventType;
}
}
var nextSibling1 = node.nextSibling;
if (nextSibling1) {
return this.enter(nextSibling1);
} else {
var parentNode = node.parentNode;
this.node = parentNode;
this.attributes = null;
if (parentNode.nodeType === 9) {
this.eventType = 8;
} else {
this.eventType = 2;
}
return this.eventType;
}
},
getName : function() {
var node = this.node;
if (Jsonix.Util.Type.isString(node.nodeName)) {
if (Jsonix.Util.Type.isString(node.namespaceURI)) {
return new Jsonix.XML.QName(node.namespaceURI, node.nodeName);
} else {
return new Jsonix.XML.QName(node.nodeName);
}
} else {
return null;
}
},
getNameKey : function() {
var node = this.node;
if (Jsonix.Util.Type.isString(node.nodeName)) {
return Jsonix.XML.QName.key(node.namespaceURI, node.nodeName);
} else {
return null;
}
},
getText : function() {
return this.node.nodeValue;
},
nextTag : function() {
var et = this.next();
// TODO isWhiteSpace
while (et === 7 || et === 4 || et === 12 || et === 6 || et === 3 || et === 5) {
et = this.next();
}
if (et !== 1 && et !== 2) {
// TODO location
throw new Error('Expected start or end tag.');
}
return et;
},
skipElement : function() {
if (this.eventType !== Jsonix.XML.Input.START_ELEMENT) {
throw new Error("Parser must be on START_ELEMENT to skip element.");
}
var numberOfOpenTags = 1;
var et;
do {
et = this.nextTag();
numberOfOpenTags += (et === Jsonix.XML.Input.START_ELEMENT) ? 1 : -1;
} while (numberOfOpenTags > 0);
return et;
},
getElementText : function() {
if (this.eventType != 1) {
throw new Error("Parser must be on START_ELEMENT to read next text.");
}
var et = this.next();
var content = '';
while (et !== 2) {
if (et === 4 || et === 12 || et === 6 || et === 9) {
content = content + this.getText();
} else if (et === 3 || et === 5) {
// Skip PI or comment
} else if (et === 8) {
// End document
throw new Error("Unexpected end of document when reading element text content.");
} else if (et === 1) {
// End element
// TODO location
throw new Error("Element text content may not contain START_ELEMENT.");
} else {
// TODO location
throw new Error("Unexpected event type [" + et + "].");
}
et = this.next();
}
return content;
},
retrieveElement : function () {
var element;
if (this.eventType === 1) {
element = this.node;
} else if (this.eventType === 10) {
element = this.node.parentNode;
} else {
throw new Error("Element can only be retrieved for START_ELEMENT or ATTRIBUTE nodes.");
}
return element;
},
retrieveAttributes : function () {
var attributes;
if (this.attributes)
{
attributes = this.attributes;
} else if (this.eventType === 1) {
attributes = this.node.attributes;
this.attributes = attributes;
} else if (this.eventType === 10) {
attributes = this.node.parentNode.attributes;
this.attributes = attributes;
} else {
throw new Error("Attributes can only be retrieved for START_ELEMENT or ATTRIBUTE nodes.");
}
return attributes;
},
getAttributeCount : function() {
var attributes = this.retrieveAttributes();
return attributes.length;
},
getAttributeName : function(index) {
var attributes = this.retrieveAttributes();
if (index < 0 || index >= attributes.length) {
throw new Error("Invalid attribute index [" + index + "].");
}
var attribute = attributes[index];
if (Jsonix.Util.Type.isString(attribute.namespaceURI)) {
return new Jsonix.XML.QName(attribute.namespaceURI, attribute.nodeName);
} else {
return new Jsonix.XML.QName(attribute.nodeName);
}
},
getAttributeNameKey : function(index) {
var attributes = this.retrieveAttributes();
if (index < 0 || index >= attributes.length) {
throw new Error("Invalid attribute index [" + index + "].");
}
var attribute = attributes[index];
return Jsonix.XML.QName.key(attribute.namespaceURI, attribute.nodeName);
},
getAttributeValue : function(index) {
var attributes = this.retrieveAttributes();
if (index < 0 || index >= attributes.length) {
throw new Error("Invalid attribute index [" + index + "].");
}
var attribute = attributes[index];
return attribute.value;
},
getAttributeValueNS : null,
getAttributeValueNSViaElement : function(namespaceURI, localPart) {
var element = this.retrieveElement();
return element.getAttributeNS(namespaceURI, localPart);
},
getAttributeValueNSViaAttribute : function(namespaceURI, localPart) {
var attributeNode = this.getAttributeNodeNS(namespaceURI, localPart);
if (Jsonix.Util.Type.exists(attributeNode)) {
return attributeNode.nodeValue;
}
else
{
return null;
}
},
getAttributeNodeNS : null,
getAttributeNodeNSViaElement : function(namespaceURI, localPart) {
var element = this.retrieveElement();
return element.getAttributeNodeNS(namespaceURI, localPart);
},
getAttributeNodeNSViaAttributes : function(namespaceURI, localPart) {
var attributeNode = null;
var attributes = this.retrieveAttributes();
var potentialNode, fullName;
for (var i = 0, len = attributes.length; i < len; ++i) {
potentialNode = attributes[i];
if (potentialNode.namespaceURI === namespaceURI) {
fullName = (potentialNode.prefix) ? (potentialNode.prefix + ':' + localPart) : localPart;
if (fullName === potentialNode.nodeName) {
attributeNode = potentialNode;
break;
}
}
}
return attributeNode;
},
getElement : function() {
if (this.eventType === 1 || this.eventType === 2) {
// Go to the END_ELEMENT
this.eventType = 2;
return this.node;
} else {
throw new Error("Parser must be on START_ELEMENT or END_ELEMENT to return current element.");
}
},
pushNS : function (node) {
var pindex = this.pns.length - 1;
var parentPnsItem = this.pns[pindex];
var pnsItem = Jsonix.Util.Type.isObject(parentPnsItem) ? pindex : parentPnsItem;
this.pns.push(pnsItem);
pindex++;
var reference = true;
if (node.attributes)
{
var attributes = node.attributes;
var alength = attributes.length;
if (alength > 0)
{
// If given node has attributes
for (var aindex = 0; aindex < alength; aindex++)
{
var attribute = attributes[aindex];
var attributeName = attribute.nodeName;
var p = null;
var ns = null;
var isNS = false;
if (attributeName === 'xmlns')
{
p = '';
ns = attribute.value;
isNS = true;
}
else if (attributeName.substring(0, 6) === 'xmlns:')
{
p = attributeName.substring(6);
ns = attribute.value;
isNS = true;
}
// Attribute is a namespace declaration
if (isNS)
{
if (reference)
{
pnsItem = Jsonix.Util.Type.cloneObject(this.pns[pnsItem], {});
this.pns[pindex] = pnsItem;
reference = false;
}
pnsItem[p] = ns;
}
}
}
}
},
popNS : function () {
this.pns.pop();
},
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.Input"
});
Jsonix.XML.Input.prototype.getAttributeValueNS = (Jsonix.DOM.isDomImplementationAvailable()) ? Jsonix.XML.Input.prototype.getAttributeValueNSViaElement : Jsonix.XML.Input.prototype.getAttributeValueNSViaAttribute;
Jsonix.XML.Input.prototype.getAttributeNodeNS = (Jsonix.DOM.isDomImplementationAvailable()) ? Jsonix.XML.Input.prototype.getAttributeNodeNSViaElement : Jsonix.XML.Input.prototype.getAttributeNodeNSViaAttributes;
Jsonix.XML.Input.START_ELEMENT = 1;
Jsonix.XML.Input.END_ELEMENT = 2;
Jsonix.XML.Input.PROCESSING_INSTRUCTION = 3;
Jsonix.XML.Input.CHARACTERS = 4;
Jsonix.XML.Input.COMMENT = 5;
Jsonix.XML.Input.SPACE = 6;
Jsonix.XML.Input.START_DOCUMENT = 7;
Jsonix.XML.Input.END_DOCUMENT = 8;
Jsonix.XML.Input.ENTITY_REFERENCE = 9;
Jsonix.XML.Input.ATTRIBUTE = 10;
Jsonix.XML.Input.DTD = 11;
Jsonix.XML.Input.CDATA = 12;
Jsonix.XML.Input.NAMESPACE = 13;
Jsonix.XML.Input.NOTATION_DECLARATION = 14;
Jsonix.XML.Input.ENTITY_DECLARATION = 15;
© 2015 - 2024 Weber Informatics LLC | Privacy Policy