diff --git a/chrome/content/zotero/xpcom/data/relation.js b/chrome/content/zotero/xpcom/data/relation.js
index c6997732e..1d2f8272f 100644
--- a/chrome/content/zotero/xpcom/data/relation.js
+++ b/chrome/content/zotero/xpcom/data/relation.js
@@ -223,13 +223,23 @@ Zotero.Relation.prototype.erase = function () {
}
-Zotero.Relation.prototype.toXML = function () {
- var xml = ;
- xml.@libraryID = this.libraryID;
- xml.subject = this.subject;
- xml.predicate = this.predicate;
- xml.object = this.object;
- return xml;
+Zotero.Relation.prototype.toXML = function (doc) {
+ var relationXML = doc.createElement('relation');
+ relationXML.setAttribute('libraryID', this.libraryID);
+
+ var elem = doc.createElement('subject');
+ elem.appendChild(doc.createTextNode(this.subject));
+ relationXML.appendChild(elem);
+
+ var elem = doc.createElement('predicate');
+ elem.appendChild(doc.createTextNode(this.predicate));
+ relationXML.appendChild(elem);
+
+ var elem = doc.createElement('object');
+ elem.appendChild(doc.createTextNode(this.object));
+ relationXML.appendChild(elem);
+
+ return relationXML;
}
diff --git a/chrome/content/zotero/xpcom/data/relations.js b/chrome/content/zotero/xpcom/data/relations.js
index 70f0ab431..798825668 100644
--- a/chrome/content/zotero/xpcom/data/relations.js
+++ b/chrome/content/zotero/xpcom/data/relations.js
@@ -239,9 +239,9 @@ Zotero.Relations = new function () {
}
- this.xmlToRelation = function (xml) {
+ this.xmlToRelation = function (relationNode) {
var relation = new Zotero.Relation;
- var libraryID = xml.@libraryID.toString();
+ var libraryID = relationNode.getAttribute('libraryID');
if (libraryID) {
relation.libraryID = parseInt(libraryID);
}
@@ -252,9 +252,9 @@ Zotero.Relations = new function () {
}
relation.libraryID = parseInt(libraryID);
}
- relation.subject = xml.subject.toString();
- relation.predicate = xml.predicate.toString();
- relation.object = xml.object.toString();
+ relation.subject = _getFirstChildContent(relationNode, 'subject');
+ relation.predicate = _getFirstChildContent(relationNode, 'predicate');
+ relation.object = _getFirstChildContent(relationNode, 'object');
return relation;
}
diff --git a/chrome/content/zotero/xpcom/sync.js b/chrome/content/zotero/xpcom/sync.js
index e2e535673..a20857416 100644
--- a/chrome/content/zotero/xpcom/sync.js
+++ b/chrome/content/zotero/xpcom/sync.js
@@ -55,8 +55,6 @@ Zotero.Sync = new function() {
};
});
- default xml namespace = '';
-
var _typesLoaded = false;
var _objectTypeIDs = {};
var _objectTypeNames = {};
@@ -372,8 +370,6 @@ Zotero.Sync.ObjectKeySet.prototype.removeLibraryKeyPairs = function (type, keyPa
* plus related methods
*/
Zotero.Sync.EventListener = new function () {
- default xml namespace = '';
-
this.init = init;
this.ignoreDeletions = ignoreDeletions;
this.notify = notify;
@@ -1196,8 +1192,6 @@ Zotero.Sync.Server = new function () {
this.nextLocalSyncDate = false;
this.apiVersion = 9;
- default xml namespace = '';
-
var _loginManagerHost = 'chrome://zotero';
var _loginManagerURL = 'Zotero Sync Server';
@@ -1371,22 +1365,20 @@ Zotero.Sync.Server = new function () {
}
try {
- var xml = xmlhttp.responseText.replace(/^\s*<\?xml.*\?>\s*/, '').trim();
+ var responseNode = xmlhttp.responseXML.documentElement;
- // Strip XML declaration and convert to E4X
- xml = new XML(xml);
-
- var updateKey = xml.@updateKey.toString();
+ var updateKey = responseNode.getAttribute('updateKey');
// If no earliest date is provided by the server, the server
// account is empty
- var earliestRemoteDate = parseInt(xml.@earliest) ?
- new Date((xml.@earliest + 43200) * 1000) : false;
+ var earliestRemoteDate = responseNode.getAttribute('earliest');
+ earliestRemoteDate = parseInt(earliestRemoteDate) ?
+ new Date((earliestRemoteDate + 43200) * 1000) : false;
var noServerData = !!earliestRemoteDate;
// Check to see if we're syncing with a different user
- var userID = parseInt(xml.@userID);
- var libraryID = parseInt(xml.@defaultLibraryID);
+ var userID = parseInt(responseNode.getAttribute('userID'));
+ var libraryID = parseInt(responseNode.getAttribute('defaultLibraryID'));
var c = _checkSyncUser(userID, libraryID, noServerData);
if (c == 0) {
// Groups were deleted, so restart sync
@@ -1461,7 +1453,7 @@ Zotero.Sync.Server = new function () {
try {
var gen = Zotero.Sync.Server.Data.processUpdatedXML(
- xml.updated,
+ responseNode.getElementsByTagName('updated')[0],
lastLocalSyncDate,
syncSession,
libraryID,
@@ -2456,48 +2448,34 @@ Zotero.Sync.Server.Session.prototype._removeFromKeySet = function (keySet, objs)
Zotero.Sync.Server.Data = new function() {
- this.processUpdatedXML = processUpdatedXML;
- this.itemToXML = itemToXML;
- this.xmlToItem = xmlToItem;
- this.removeMissingRelatedItems = removeMissingRelatedItems;
- this.collectionToXML = collectionToXML;
- this.xmlToCollection = xmlToCollection;
- this.creatorToXML = creatorToXML;
- this.xmlToCreator = xmlToCreator;
- this.searchToXML = searchToXML;
- this.xmlToSearch = xmlToSearch;
- this.tagToXML = tagToXML;
- this.xmlToTag = xmlToTag;
-
var _noMergeTypes = ['search'];
- default xml namespace = '';
-
-
/**
* Pull out collections from delete queue in XML
*
- * @param {XML} xml
+ * @param {DOMNode} xml
* @return {String[]} Array of collection keys
*/
- function _getDeletedCollectionKeys(xml) {
+ function _getDeletedCollectionKeys(updatedNode) {
var keys = [];
- if (xml.deleted && xml.deleted.collections) {
- for each(var xmlNode in xml.deleted.collections.collection) {
- var libraryID = xmlNode.@libraryID.toString();
- libraryID = libraryID ? parseInt(libraryID) : null;
- keys.push({
- libraryID: libraryID,
- key: xmlNode.@key.toString()
- });
- }
+ for each(var c in updatedNode.xpath("deleted/collections/collection")) {
+ var libraryID = c.getAttribute('libraryID');
+ libraryID = libraryID ? parseInt(libraryID) : null;
+ keys.push({
+ libraryID: libraryID,
+ key: c.getAttribute('key')
+ });
}
return keys;
}
- function processUpdatedXML(xml, lastLocalSyncDate, syncSession, defaultLibraryID, callback) {
- if (xml.children().length() == 0) {
+ this.processUpdatedXML = function (updatedNode, lastLocalSyncDate, syncSession, defaultLibraryID, callback) {
+ updatedNode.xpath = function (path) {
+ return Zotero.Utilities.xpath(this, path);
+ };
+
+ if (updatedNode.childNodes.length == 0) {
Zotero.debug('No changes received from server');
callback(Zotero.Sync.Server.Data.buildUploadXML(syncSession));
return;
@@ -2520,7 +2498,7 @@ Zotero.Sync.Server.Data = new function() {
var repaintTime = 100;
var lastRepaint = Date.now();
- var deletedCollectionKeys = _getDeletedCollectionKeys(xml);
+ var deletedCollectionKeys = _getDeletedCollectionKeys(updatedNode);
var remoteCreatorStore = {};
var relatedItemsStore = {};
@@ -2528,10 +2506,11 @@ Zotero.Sync.Server.Data = new function() {
var childItemStore = [];
// Remotely changed groups
- if (xml.groups.length()) {
+ var groupNodes = updatedNode.xpath("groups/group");
+ if (groupNodes.length) {
Zotero.debug("Processing remotely changed groups");
- for each(var xmlNode in xml.groups.group) {
- var group = Zotero.Sync.Server.Data.xmlToGroup(xmlNode);
+ for each(var groupNode in groupNodes) {
+ var group = Zotero.Sync.Server.Data.xmlToGroup(groupNode);
group.save();
}
}
@@ -2539,9 +2518,10 @@ Zotero.Sync.Server.Data = new function() {
if (_timeToYield()) yield true;
// Remotely deleted groups
- if (xml.deleted.groups.toString()) {
+ var deletedGroups = updatedNode.xpath("deleted/groups");
+ if (deletedGroups.length && deletedGroups.textContent) {
Zotero.debug("Processing remotely deleted groups");
- var groupIDs = xml.deleted.groups.toString().split(' ');
+ var groupIDs = deletedGroups.textContent.split(' ');
Zotero.debug(groupIDs);
for each(var groupID in groupIDs) {
@@ -2561,9 +2541,9 @@ Zotero.Sync.Server.Data = new function() {
// Get unmodified creators embedded within items -- this is necessary if, say,
// a creator was deleted locally and appears in a new/modified item remotely
var embeddedCreators = {};
- for each(var creatorNode in xml.items.item.creator.creator) {
- var libraryID = _libID(creatorNode.@libraryID.toString());
- var key = creatorNode.@key.toString();
+ for each(var creatorNode in updatedNode.xpath("items/item/creator/creator")) {
+ var libraryID = _libID(creatorNode.getAttribute('libraryID'));
+ var key = creatorNode.getAttribute('key');
var creatorObj = Zotero.Creators.getByLibraryAndKey(libraryID, key);
// If creator exists locally, we don't need it
@@ -2578,9 +2558,9 @@ Zotero.Sync.Server.Data = new function() {
}
// Make sure embedded creators aren't already provided in the node
// This isn't necessary if the server data is correct
- for each(var creatorNode in xml.creators.creator) {
- var libraryID = _libID(creatorNode.@libraryID.toString());
- var key = creatorNode.@key.toString();
+ for each(var creatorNode in updatedNode.xpath("creators/creator")) {
+ var libraryID = _libID(creatorNode.getAttribute('libraryID'));
+ var key = creatorNode.getAttribute('key');
var lkh = Zotero.Creators.makeLibraryKeyHash(libraryID, key);
if (embeddedCreators[lkh]) {
var msg = "Creator " + libraryID + "/" + key + " was unnecessarily embedded in server response "
@@ -2592,21 +2572,27 @@ Zotero.Sync.Server.Data = new function() {
}
// For any embedded creators that don't exist locally and aren't already
// included in the node, copy the node into for saving
- var elementCreated = !!xml.creators.length();
- for each(var creatorNode in xml.items.item.creator.creator) {
- var libraryID = _libID(creatorNode.@libraryID.toString());
- var key = creatorNode.@key.toString();
+ var creatorsNode = false;
+ for each(var creatorNode in updatedNode.xpath("items/item/creator/creator")) {
+ var libraryID = _libID(creatorNode.getAttribute('libraryID'));
+ var key = creatorNode.getAttribute('key');
var lkh = Zotero.Creators.makeLibraryKeyHash(libraryID, key);
if (embeddedCreators[lkh]) {
- if (!elementCreated) {
- xml.creators = new XML("");
- elementCreated = true;
+ if (!creatorsNode) {
+ creatorsNode = updatedNode.xpath("creators");
+ if (creatorsNode.length) {
+ creatorsNode = creatorsNode[0];
+ }
+ else {
+ creatorsNode = updatedNode.ownerDocument.createElement("creators");
+ updatedNode.appendChild(creatorsNode);
+ }
}
Zotero.debug("Adding embedded creator " + libraryID + "/" + key + " to ");
- xml.creators.appendChild(creatorNode);
+ creatorsNode.appendChild(creatorNode);
delete embeddedCreators[lkh];
}
}
@@ -2633,9 +2619,9 @@ Zotero.Sync.Server.Data = new function() {
Zotero.debug("Processing remotely changed " + types);
typeloop:
- for each(var xmlNode in xml[types][type]) {
- var libraryID = _libID(xmlNode.@libraryID.toString());
- var key = xmlNode.@key.toString();
+ for each(var objectNode in updatedNode.xpath(types + "/" + type)) {
+ var libraryID = _libID(objectNode.getAttribute('libraryID'));
+ var key = objectNode.getAttribute('key');
var objLibraryKeyHash = Zotero[Types].makeLibraryKeyHash(libraryID, key);
Zotero.debug("Processing remote " + type + " " + libraryID + "/" + key, 4);
@@ -2668,7 +2654,7 @@ Zotero.Sync.Server.Data = new function() {
// affect related items
if (type == 'item') {
// Remote
- var relKeys = xmlNode.related.toString();
+ var relKeys = _getFirstChildContent(objectNode, 'related');
relKeys = relKeys ? relKeys.split(' ') : [];
// Local
for each(var relID in obj.relatedItems) {
@@ -2680,10 +2666,10 @@ Zotero.Sync.Server.Data = new function() {
if (relKeys.length) {
relatedItemsStore[objLibraryKeyHash] = relKeys;
}
- Zotero.Sync.Server.Data.removeMissingRelatedItems(xmlNode);
+ Zotero.Sync.Server.Data.removeMissingRelatedItems(objectNode);
}
- var remoteObj = Zotero.Sync.Server.Data['xmlTo' + Type](xmlNode, null, null, defaultLibraryID);
+ var remoteObj = Zotero.Sync.Server.Data['xmlTo' + Type](objectNode, null, null, defaultLibraryID);
// Some types we don't bother to reconcile
if (_noMergeTypes.indexOf(type) != -1) {
@@ -2822,13 +2808,13 @@ Zotero.Sync.Server.Data = new function() {
syncSession.removeFromDeleted(fakeObj);
var msg = _generateAutoChangeLogMessage(
- type, null, xmlNode.@name.toString()
+ type, null, objectNode.getAttribute('name')
);
Zotero.log(msg, 'warning');
if (!syncSession.suppressWarnings) {
var msg = _generateAutoChangeAlertMessage(
- types, null, xmlNode.@name.toString()
+ types, null, objectNode.getAttribute('name')
);
alert(msg);
syncSession.suppressWarnings = true;
@@ -2848,7 +2834,7 @@ Zotero.Sync.Server.Data = new function() {
// Temporarily remove and store related items that don't yet exist
if (type == 'item') {
- var missing = Zotero.Sync.Server.Data.removeMissingRelatedItems(xmlNode);
+ var missing = Zotero.Sync.Server.Data.removeMissingRelatedItems(objectNode);
if (missing.length) {
relatedItemsStore[objLibraryKeyHash] = missing;
}
@@ -2858,7 +2844,7 @@ Zotero.Sync.Server.Data = new function() {
//
// If we skipped CR above, we already have an object to use
if (!skipCR) {
- obj = Zotero.Sync.Server.Data['xmlTo' + Type](xmlNode, obj, false, defaultLibraryID, deletedItemKeys);
+ obj = Zotero.Sync.Server.Data['xmlTo' + Type](objectNode, obj, false, defaultLibraryID, deletedItemKeys);
}
if (isNewObject && type == 'tag') {
@@ -2866,10 +2852,10 @@ Zotero.Sync.Server.Data = new function() {
// delete the local tag and add items linked to it to the
// matching remote tag
//
- // DEBUG: why use xmlNode?
- var tagName = xmlNode.@name.toString();
- var tagType = xmlNode.@type.toString()
- ? parseInt(xmlNode.@type) : 0;
+ // DEBUG: why use objectNode?
+ var tagName = objectNode.getAttribute('name');
+ var tagType = objectNode.getAttribute('type');
+ tagType = tagType ? parseInt(tagType) : 0;
var linkedItems = _deleteConflictingTag(syncSession, tagName, tagType, obj.libraryID);
if (linkedItems) {
var mod = false;
@@ -2884,7 +2870,7 @@ Zotero.Sync.Server.Data = new function() {
syncSession.addToUpdated({
objectType: 'tag',
libraryID: obj.libraryID,
- key: xmlNode.@key
+ key: objectNode.getAttribute('key')
});
}
}
@@ -2921,7 +2907,7 @@ Zotero.Sync.Server.Data = new function() {
}
// Set existing attachments mtime update check
else {
- var mtime = xmlNode.@storageModTime.toString();
+ var mtime = objectNode.getAttribute('storageModTime');
if (mtime) {
var lk = Zotero.Items.getLibraryKeyHash(obj)
// Convert previously used Unix timestamps to ms-based timestamps
@@ -2996,14 +2982,15 @@ Zotero.Sync.Server.Data = new function() {
//
// Handle remotely deleted objects
//
- if (xml.deleted.length() && xml.deleted[types].length()) {
+ var deletedObjectNodes = updatedNode.xpath("deleted/" + types + "/" + type);
+ if (deletedObjectNodes.length) {
Zotero.debug("Processing remotely deleted " + types);
syncSession.suppressWarnings = false;
- for each(var xmlNode in xml.deleted[types][type]) {
- var libraryID = _libID(xmlNode.@libraryID.toString());
- var key = xmlNode.@key.toString();
+ for each(var delNode in deletedObjectNodes) {
+ var libraryID = _libID(delNode.getAttribute('libraryID'));
+ var key = delNode.getAttribute('key');
var obj = Zotero[Types].getByLibraryAndKey(libraryID, key);
// Object can't be found
if (!obj) {
@@ -3273,7 +3260,7 @@ Zotero.Sync.Server.Data = new function() {
var keys = syncSession.uploadKeys;
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
- .createInstance(Components.interfaces.nsIDOMParser);
+ .createInstance(Components.interfaces.nsIDOMParser);
var doc = parser.parseFromString("", "text/xml");
var docElem = doc.documentElement;
@@ -3286,7 +3273,7 @@ Zotero.Sync.Server.Data = new function() {
var Types = syncObject.plural; // 'Items'
var type = Type.toLowerCase(); // 'item'
var types = Types.toLowerCase(); // 'items'
- var xmlObjectsNode = false;
+ var objectsNode = false;
Zotero.debug("Processing locally changed " + types);
@@ -3294,8 +3281,8 @@ Zotero.Sync.Server.Data = new function() {
for (var libraryID in keys.updated[types]) {
for (var key in keys.updated[types][libraryID]) {
// Insert the <[types]> node
- if (!xmlObjectsNode) {
- xmlObjectsNode = docElem.appendChild(doc.createElement(types));
+ if (!objectsNode) {
+ objectsNode = docElem.appendChild(doc.createElement(types));
}
var l = parseInt(libraryID);
@@ -3313,19 +3300,19 @@ Zotero.Sync.Server.Data = new function() {
if (type == 'item') {
// itemToXML needs the sync session
- var str = this.itemToXML(obj, syncSession).toXMLString();
+ var elem = this.itemToXML(obj, doc, syncSession);
}
else {
- var str = this[type + 'ToXML'](obj).toXMLString();
+ var elem = this[type + 'ToXML'](obj, doc);
}
- xmlObjectsNode.appendChild(doc.createRange().createContextualFragment(str));
+ objectsNode.appendChild(elem);
}
}
}
// Deletions
- var xmlDeletedNode = doc.createElement('deleted');
+ var deletedNode = doc.createElement('deleted');
var inserted = false;
var defaultLibraryID = Zotero.libraryID;
@@ -3335,7 +3322,7 @@ Zotero.Sync.Server.Data = new function() {
var Types = syncObject.plural; // 'Items'
var type = Type.toLowerCase(); // 'item'
var types = Types.toLowerCase(); // 'items'
- var xmlDeletedObjectsNode = false;
+ var deletedObjectsNode = false;
Zotero.debug('Processing locally deleted ' + types);
@@ -3345,18 +3332,18 @@ Zotero.Sync.Server.Data = new function() {
for (var key in keys.deleted[types][libraryID]) {
// Insert the node
if (!inserted) {
- docElem.appendChild(xmlDeletedNode);
+ docElem.appendChild(deletedNode);
inserted = true;
}
// Insert the <[types]> node
- if (!xmlDeletedObjectsNode) {
- xmlDeletedObjectsNode = xmlDeletedNode.appendChild(doc.createElement(types));
+ if (!deletedObjectsNode) {
+ deletedObjectsNode = deletedNode.appendChild(doc.createElement(types));
}
var n = doc.createElement(type);
n.setAttribute('libraryID', parseInt(libraryID) ? parseInt(libraryID) : defaultLibraryID);
n.setAttribute('key', key);
- xmlDeletedObjectsNode.appendChild(n);
+ deletedObjectsNode.appendChild(n);
}
}
}
@@ -3367,7 +3354,7 @@ Zotero.Sync.Server.Data = new function() {
var xmlstr = s.serializeToString(doc);
// No updated data
- if (xmlstr.match('')) {
+ if (docElem.childNodes.length == 0) {
return '';
}
@@ -3764,17 +3751,18 @@ Zotero.Sync.Server.Data = new function() {
/**
- * Converts a Zotero.Item object to an E4X - object
+ * Converts a Zotero.Item object to a DOM
- node
*
- * @param {Zotero.Item} item
- * @param {Zotero.Sync.Server.Session} [syncSession]
+ * @param {Zotero.Item} item
+ * @param {DOMDocument} doc
+ * @param {Zotero.Sync.Server.Session} [syncSession]
*/
- function itemToXML(item, syncSession) {
- var xml =
;
+ this.itemToXML = function (item, doc, syncSession) {
var item = item.serialize();
- xml.@libraryID = item.primary.libraryID ? item.primary.libraryID : Zotero.libraryID;
- xml.@key = item.primary.key;
+ var itemNode = doc.createElement('item');
+ itemNode.setAttribute('libraryID', item.primary.libraryID ? item.primary.libraryID : Zotero.libraryID);
+ itemNode.setAttribute('key', item.primary.key);
// Primary fields
for (var field in item.primary) {
@@ -3787,7 +3775,7 @@ Zotero.Sync.Server.Data = new function() {
default:
var attr = field;
}
- xml['@' + attr] = item.primary[field];
+ itemNode.setAttribute(attr, item.primary[field]);
}
// Item data
@@ -3795,35 +3783,37 @@ Zotero.Sync.Server.Data = new function() {
if (!item.fields[field]) {
continue;
}
- var newField = {_xmlize(item.fields[field])};
- newField.@name = field;
- xml.appendChild(newField);
+ var fieldElem = doc.createElement('field');
+ fieldElem.setAttribute('name', field);
+ fieldElem.appendChild(doc.createTextNode(_xmlize(item.fields[field])));
+ itemNode.appendChild(fieldElem);
}
// Deleted item flag
if (item.deleted) {
- xml.@deleted = '1';
+ itemNode.setAttribute('deleted', '1');
}
if (item.primary.itemType == 'note' || item.primary.itemType == 'attachment') {
if (item.sourceItemKey) {
- xml.@sourceItem = item.sourceItemKey;
+ itemNode.setAttribute('sourceItem', item.sourceItemKey);
}
}
// Note
if (item.primary.itemType == 'note') {
- var note = {_xmlize(item.note)};
- xml.appendChild(note);
+ var noteElem = doc.createElement('note');
+ noteElem.appendChild(doc.createTextNode(_xmlize(item.note)));
+ itemNode.appendChild(noteElem);
}
// Attachment
if (item.primary.itemType == 'attachment') {
- xml.@linkMode = item.attachment.linkMode;
- xml.@mimeType = item.attachment.mimeType;
+ itemNode.setAttribute('linkMode', item.attachment.linkMode);
+ itemNode.setAttribute('mimeType', item.attachment.mimeType);
var charset = item.attachment.charset;
if (charset) {
- xml.@charset = charset;
+ itemNode.setAttribute('charset', charset);
}
if (item.attachment.linkMode != Zotero.Attachments.LINK_MODE_LINKED_URL) {
@@ -3838,33 +3828,35 @@ Zotero.Sync.Server.Data = new function() {
throw (e);
}
- path = {path};
- xml.appendChild(path);
+ var pathElem = doc.createElement('path');
+ pathElem.appendChild(doc.createTextNode(path));
+ itemNode.appendChild(pathElem);
// Include storage sync time and hash for imported files
if (item.attachment.linkMode != Zotero.Attachments.LINK_MODE_LINKED_FILE) {
var mtime = Zotero.Sync.Storage.getSyncedModificationTime(item.primary.itemID);
if (mtime) {
- xml.@storageModTime = mtime;
+ itemNode.setAttribute('storageModTime', mtime);
}
var hash = Zotero.Sync.Storage.getSyncedHash(item.primary.itemID);
if (hash) {
- xml.@storageHash = hash;
+ itemNode.setAttribute('storageHash', hash);
}
}
}
if (item.note) {
- var note = {_xmlize(item.note)};
- xml.appendChild(note);
+ var noteElem = doc.createElement('note');
+ noteElem.appendChild(doc.createTextNode(_xmlize(item.note)));
+ itemNode.appendChild(noteElem);
}
}
// Creators
var defaultLibraryID = Zotero.libraryID;
for (var index in item.creators) {
- var newCreator = ;
+ var creatorElem = doc.createElement('creator');
var libraryID = item.creators[index].libraryID ? item.creators[index].libraryID : defaultLibraryID;
var key = item.creators[index].key;
if (!key) {
@@ -3873,10 +3865,10 @@ Zotero.Sync.Server.Data = new function() {
Zotero.debug(item);
throw ("Creator key not set for item in Zotero.Sync.Server.sync()");
}
- newCreator.@libraryID = libraryID;
- newCreator.@key = key;
- newCreator.@creatorType = item.creators[index].creatorType;
- newCreator.@index = index;
+ creatorElem.setAttribute('libraryID', libraryID);
+ creatorElem.setAttribute('key', key);
+ creatorElem.setAttribute('creatorType', item.creators[index].creatorType);
+ creatorElem.setAttribute('index', index);
// Add creator XML as glue if not already included in sync session
var fakeObj = {
@@ -3886,11 +3878,11 @@ Zotero.Sync.Server.Data = new function() {
};
if (syncSession && syncSession.objectInUpdated(fakeObj)) {
var creator = Zotero.Creators.getByLibraryAndKey(libraryID, key);
- var creatorXML = Zotero.Sync.Server.Data.creatorToXML(creator);
- newCreator.creator = creatorXML;
+ var subCreatorElem = Zotero.Sync.Server.Data.creatorToXML(creator, doc);
+ creatorElem.appendChild(subCreatorElem);
}
- xml.appendChild(newCreator);
+ itemNode.appendChild(creatorElem);
}
// Related items
@@ -3902,22 +3894,24 @@ Zotero.Sync.Server.Data = new function() {
keys.push(item.key);
}
if (keys.length) {
- xml.related = keys.join(' ');
+ var relatedElem = doc.createElement('related');
+ relatedElem.appendChild(doc.createTextNode(keys.join(' ')));
+ itemNode.appendChild(relatedElem);
}
}
- return xml;
+ return itemNode;
}
/**
- * Convert E4X - object into an unsaved Zotero.Item
+ * Convert DOM
- node into an unsaved Zotero.Item
*
- * @param object xmlItem E4X XML node with item data
+ * @param object itemNode DOM XML node with item data
* @param object item (Optional) Existing Zotero.Item to update
* @param bool skipPrimary (Optional) Ignore passed primary fields (except itemTypeID)
*/
- function xmlToItem(xmlItem, item, skipPrimary, defaultLibraryID) {
+ this.xmlToItem = function (itemNode, item, skipPrimary, defaultLibraryID) {
if (!item) {
item = new Zotero.Item;
}
@@ -3930,15 +3924,15 @@ Zotero.Sync.Server.Data = new function() {
var data = {};
if (!skipPrimary) {
- data.libraryID = _getLibraryID(xmlItem.@libraryID.toString(), defaultLibraryID);
- data.key = xmlItem.@key.toString();
- data.dateAdded = xmlItem.@dateAdded.toString();
- data.dateModified = xmlItem.@dateModified.toString();
+ data.libraryID = _getLibraryID(itemNode.getAttribute('libraryID'), defaultLibraryID);
+ data.key = itemNode.getAttribute('key');
+ data.dateAdded = itemNode.getAttribute('dateAdded');
+ data.dateModified = itemNode.getAttribute('dateModified');
}
- data.itemTypeID = Zotero.ItemTypes.getID(xmlItem.@itemType.toString());
+ data.itemTypeID = Zotero.ItemTypes.getID(itemNode.getAttribute('itemType'));
// TEMP - NSF
if (!data.itemTypeID) {
- var msg = "Invalid item type '" + xmlItem.@itemType.toString() + "' in Zotero.Sync.Server.Data.xmlToItem()";
+ var msg = "Invalid item type '" + itemNode.getAttribute('itemType') + "' in Zotero.Sync.Server.Data.xmlToItem()";
var e = new Zotero.Error(msg, "INVALID_ITEM_TYPE");
throw (e);
}
@@ -3952,9 +3946,10 @@ Zotero.Sync.Server.Data = new function() {
}
// Item data
- for each(var field in xmlItem.field) {
- var fieldName = field.@name.toString();
- item.setField(fieldName, field.toString());
+ var fields = itemNode.getElementsByTagName('field');
+ for each(var field in fields) {
+ var fieldName = field.getAttribute('name');
+ item.setField(fieldName, field.textContent);
changedFields[fieldName] = true;
}
var previousFields = item.getUsedFields(true);
@@ -3970,19 +3965,20 @@ Zotero.Sync.Server.Data = new function() {
}
// Deleted item flag
- var deleted = xmlItem.@deleted.toString();
+ var deleted = itemNode.getAttribute('deleted');
item.deleted = (deleted == 'true' || deleted == "1");
// Item creators
var i = 0;
- for each(var creator in xmlItem.creator) {
- var pos = parseInt(creator.@index);
+ var creators = Zotero.Utilities.xpath(itemNode, "creator");
+ for each(var creator in creators) {
+ var pos = parseInt(creator.getAttribute('index'));
if (pos != i) {
throw ('No creator in position ' + i);
}
var libraryID = data.libraryID;
- var key = creator.@key.toString();
+ var key = creator.getAttribute('key');
var creatorObj = Zotero.Creators.getByLibraryAndKey(libraryID, key);
if (!creatorObj) {
var msg = "Data for missing local creator " + libraryID + "/" + key
@@ -3994,7 +3990,7 @@ Zotero.Sync.Server.Data = new function() {
item.setCreator(
pos,
creatorObj,
- creator.@creatorType.toString()
+ creator.getAttribute('creatorType')
);
i++;
}
@@ -4009,23 +4005,23 @@ Zotero.Sync.Server.Data = new function() {
// Both notes and attachments might have parents and notes
if (item.isNote() || item.isAttachment()) {
- var sourceItemKey = xmlItem.@sourceItem.toString();
+ var sourceItemKey = itemNode.getAttribute('sourceItem');
item.setSourceKey(sourceItemKey ? sourceItemKey : false);
- item.setNote(xmlItem.note.toString());
+ item.setNote(_getFirstChildContent(itemNode, 'note'));
}
// Attachment metadata
if (item.isAttachment()) {
- item.attachmentLinkMode = parseInt(xmlItem.@linkMode);
- item.attachmentMIMEType = xmlItem.@mimeType.toString();
- item.attachmentCharset = xmlItem.@charset.toString();
+ item.attachmentLinkMode = parseInt(itemNode.getAttribute('linkMode'));
+ item.attachmentMIMEType = itemNode.getAttribute('mimeType');
+ item.attachmentCharset = itemNode.getAttribute('charset');
if (item.attachmentLinkMode != Zotero.Attachments.LINK_MODE_LINKED_URL) {
- item.attachmentPath = xmlItem.path.toString();
+ item.attachmentPath = _getFirstChildContent(itemNode, 'path');
}
}
// Related items
- var related = xmlItem.related.toString();
+ var related = _getFirstChildContent(itemNode, 'related');
var relatedIDs = [];
if (related) {
related = related.split(' ');
@@ -4046,11 +4042,16 @@ Zotero.Sync.Server.Data = new function() {
}
- function removeMissingRelatedItems(xmlNode) {
- var libraryID = parseInt(xmlNode.@libraryID);
+ this.removeMissingRelatedItems = function (itemNode) {
+ var relatedNode = Zotero.Utilities.xpath(itemNode, "related");
+ if (!relatedNode.length) {
+ return [];
+ }
+ relatedNode = relatedNode[0];
+ var libraryID = parseInt(itemNode.getAttribute('libraryID'));
var exist = [];
var missing = [];
- var relKeys = xmlNode.related.toString();
+ var relKeys = relatedNode.textContent;
relKeys = relKeys ? relKeys.split(' ') : [];
for each(var relKey in relKeys) {
if (Zotero.Items.getByLibraryAndKey(libraryID, relKey)) {
@@ -4060,62 +4061,62 @@ Zotero.Sync.Server.Data = new function() {
missing.push(relKey);
}
}
- xmlNode.related = exist.join(' ');
+ relatedNode.textContent = exist.join(' ');
return missing;
}
- function collectionToXML(collection) {
- var xml = ;
- xml.@libraryID = collection.libraryID ? collection.libraryID : Zotero.libraryID;
- xml.@key = collection.key;
- xml.@name = _xmlize(collection.name);
- xml.@dateAdded = collection.dateAdded;
- xml.@dateModified = collection.dateModified;
+ this.collectionToXML = function (collection, doc) {
+ var colElem = doc.createElement('collection');
+ colElem.setAttribute('libraryID', collection.libraryID ? collection.libraryID : Zotero.libraryID);
+ colElem.setAttribute('key', collection.key);
+ colElem.setAttribute('name', _xmlize(collection.name));
+ colElem.setAttribute('dateAdded', collection.dateAdded);
+ colElem.setAttribute('dateModified', collection.dateModified);
if (collection.parent) {
var parentCol = Zotero.Collections.get(collection.parent);
- xml.@parent = parentCol.key;
+ colElem.setAttribute('parent', parentCol.key);
}
var children = collection.getChildren();
if (children) {
- //xml.collections = '';
- xml.items = '';
+ //var collectionKeys = [];
+ var itemKeys = [];
+
for each(var child in children) {
/*
if (child.type == 'collection') {
- xml.collections = xml.collections ?
- xml.collections + ' ' + child.id : child.id;
+ collectionKeys.push(child.key);
}
else */if (child.type == 'item') {
- xml.items = xml.items.toString() ?
- xml.items + ' ' + child.key : child.key;
+ itemKeys.push(child.key);
}
}
- /*
- if (xml.collections == '') {
- delete xml.collections;
- }
- */
- if (xml.items == '') {
- delete xml.items;
+
+ /*if (collectionKeys.length) {
+ var collectionsElem = doc.createElement('collections');
+ collectionsElem.appendChild(doc.createTextNode(collectionKeys.join(' ')));
+ }*/
+ if (itemKeys.length) {
+ var itemsElem = doc.createElement('items');
+ itemsElem.textContent(itemKeys.join(' '));
}
}
- return xml;
+ return colElem;
}
/**
- * Convert E4X object into an unsaved Zotero.Collection
+ * Convert DOM node into an unsaved Zotero.Collection
*
- * @param object xmlCollection E4X XML node with collection data
+ * @param object collectionNode DOM XML node with collection data
* @param object item (Optional) Existing Zotero.Collection to update
* @param bool skipPrimary (Optional) Ignore passed primary fields (except itemTypeID)
* @param integer defaultLibraryID (Optional)
* @param array deletedItems (Optional) An array of keys that have been deleted in this sync session
*/
- function xmlToCollection(xmlCollection, collection, skipPrimary, defaultLibraryID, deletedItemKeys) {
+ this.xmlToCollection = function (collectionNode, collection, skipPrimary, defaultLibraryID, deletedItemKeys) {
if (!collection) {
collection = new Zotero.Collection;
}
@@ -4125,20 +4126,20 @@ Zotero.Sync.Server.Data = new function() {
}
if (!skipPrimary) {
- collection.libraryID = _getLibraryID(xmlCollection.@libraryID.toString(), defaultLibraryID);
- collection.key = xmlCollection.@key.toString();
- var parentKey = xmlCollection.@parent.toString();
+ collection.libraryID = _getLibraryID(collectionNode.getAttribute('libraryID'), defaultLibraryID);
+ collection.key = collectionNode.getAttribute('key');
+ var parentKey = collectionNode.getAttribute('parent');
if (parentKey) {
collection.parentKey = parentKey;
}
else {
collection.parent = false;
}
- collection.dateAdded = xmlCollection.@dateAdded.toString();
- collection.dateModified = xmlCollection.@dateModified.toString();
+ collection.dateAdded = collectionNode.getAttribute('dateAdded');
+ collection.dateModified = collectionNode.getAttribute('dateModified');
}
- collection.name = xmlCollection.@name.toString();
+ collection.name = collectionNode.getAttribute('name');
/*
// Subcollections
@@ -4147,7 +4148,7 @@ Zotero.Sync.Server.Data = new function() {
*/
// Child items
- var childItems = xmlCollection.items.toString();
+ var childItems = _getFirstChildContent(collectionNode, 'items');
childItems = childItems ? childItems.split(' ') : []
var childItemIDs = [];
for each(var key in childItems) {
@@ -4223,15 +4224,14 @@ Zotero.Sync.Server.Data = new function() {
/**
- * Converts a Zotero.Creator object to an E4X object
+ * Converts a Zotero.Creator object to a DOM node
*/
- function creatorToXML(creator) {
- var xml = ;
-
- xml.@libraryID = creator.libraryID ? creator.libraryID : Zotero.libraryID;
- xml.@key = creator.key;
- xml.@dateAdded = creator.dateAdded;
- xml.@dateModified = creator.dateModified;
+ this.creatorToXML = function (creator, doc) {
+ var creatorElem = doc.createElement('creator');
+ creatorElem.setAttribute('libraryID', creator.libraryID ? creator.libraryID : Zotero.libraryID);
+ creatorElem.setAttribute('key', creator.key);
+ creatorElem.setAttribute('dateAdded', creator.dateAdded);
+ creatorElem.setAttribute('dateModified', creator.dateModified);
var allowEmpty = ['firstName', 'lastName', 'name'];
@@ -4241,29 +4241,33 @@ Zotero.Sync.Server.Data = new function() {
continue;
}
+ var fieldElem = doc.createElement(field);
switch (field) {
case 'firstName':
case 'lastName':
case 'name':
- xml[field] = _xmlize(creator.fields[field]);
+ var val = _xmlize(creator.fields[field]);
break;
default:
- xml[field] = creator.fields[field];
+ var val = creator.fields[field];
}
+ fieldElem.appendChild(doc.createTextNode(val));
+ creatorElem.appendChild(fieldElem);
}
- return xml;
+
+ return creatorElem;
}
/**
- * Convert E4X object into an unsaved Zotero.Creator
+ * Convert DOM node into an unsaved Zotero.Creator
*
- * @param object xmlCreator E4X XML node with creator data
+ * @param object creatorNode DOM XML node with creator data
* @param object item (Optional) Existing Zotero.Creator to update
* @param bool skipPrimary (Optional) Ignore passed primary fields (except itemTypeID)
*/
- function xmlToCreator(xmlCreator, creator, skipPrimary, defaultLibraryID) {
+ this.xmlToCreator = function (creatorNode, creator, skipPrimary, defaultLibraryID) {
if (!creator) {
creator = new Zotero.Creator;
}
@@ -4273,67 +4277,66 @@ Zotero.Sync.Server.Data = new function() {
}
if (!skipPrimary) {
- creator.libraryID = _getLibraryID(xmlCreator.@libraryID.toString(), defaultLibraryID);
- creator.key = xmlCreator.@key.toString();
- creator.dateAdded = xmlCreator.@dateAdded.toString();
- creator.dateModified = xmlCreator.@dateModified.toString();
+ creator.libraryID = _getLibraryID(creatorNode.getAttribute('libraryID'), defaultLibraryID);
+ creator.key = creatorNode.getAttribute('key');
+ creator.dateAdded = creatorNode.getAttribute('dateAdded');
+ creator.dateModified = creatorNode.getAttribute('dateModified');
}
- if (xmlCreator.fieldMode == 1) {
+ if (_getFirstChildContent(creatorNode, 'fieldMode') == 1) {
creator.firstName = '';
- creator.lastName = xmlCreator.name.toString();
+ creator.lastName = _getFirstChildContent(creatorNode, 'name');
creator.fieldMode = 1;
}
else {
- creator.firstName = xmlCreator.firstName.toString();
- creator.lastName = xmlCreator.lastName.toString();
+ creator.firstName = _getFirstChildContent(creatorNode, 'firstName');
+ creator.lastName = _getFirstChildContent(creatorNode, 'lastName');
creator.fieldMode = 0;
}
- creator.birthYear = xmlCreator.birthYear.toString();
+ creator.birthYear = _getFirstChildContent(creatorNode, 'birthYear');
return creator;
}
- function searchToXML(search) {
- var xml = ;
- xml.@libraryID = search.libraryID ? search.libraryID : Zotero.libraryID;
- xml.@key = search.key;
- xml.@name = _xmlize(search.name);
- xml.@dateAdded = search.dateAdded;
- xml.@dateModified = search.dateModified;
+ this.searchToXML = function (search, doc) {
+ var searchElem = doc.createElement('search');
+ searchElem.setAttribute('libraryID', search.libraryID ? search.libraryID : Zotero.libraryID);
+ searchElem.setAttribute('key', search.key);
+ searchElem.setAttribute('name', _xmlize(search.name));
+ searchElem.setAttribute('dateAdded', search.dateAdded);
+ searchElem.setAttribute('dateModified', search.dateModified);
var conditions = search.getSearchConditions();
if (conditions) {
for each(var condition in conditions) {
- var conditionXML =
- conditionXML.@id = condition.id;
- conditionXML.@condition = condition.condition;
+ var conditionElem = doc.createElement('condition');
+ conditionElem.setAttribute('id', condition.id);
+ conditionElem.setAttribute('condition', condition.condition);
if (condition.mode) {
- conditionXML.@mode = condition.mode;
+ conditionElem.setAttribute('mode', condition.mode);
}
- conditionXML.@operator = condition.operator;
- conditionXML.@value =
- _xmlize(condition.value ? condition.value : '');
+ conditionElem.setAttribute('operator', condition.operator);
+ conditionElem.setAttribute('value', _xmlize(condition.value ? condition.value : ''));
if (condition.required) {
- conditionXML.@required = 1;
+ conditionElem.setAttribute('required', 1);
}
- xml.appendChild(conditionXML);
+ searchElem.appendChild(conditionElem);
}
}
- return xml;
+ return searchElem;
}
/**
- * Convert E4X object into an unsaved Zotero.Search
+ * Convert DOM node into an unsaved Zotero.Search
*
- * @param object xmlSearch E4X XML node with search data
+ * @param object searchNode DOM XML node with search data
* @param object item (Optional) Existing Zotero.Search to update
* @param bool skipPrimary (Optional) Ignore passed primary fields (except itemTypeID)
*/
- function xmlToSearch(xmlSearch, search, skipPrimary, defaultLibraryID) {
+ this.xmlToSearch = function (searchNode, search, skipPrimary, defaultLibraryID) {
if (!search) {
search = new Zotero.Search;
}
@@ -4343,21 +4346,22 @@ Zotero.Sync.Server.Data = new function() {
}
if (!skipPrimary) {
- search.libraryID = _getLibraryID(xmlSearch.@libraryID.toString(), defaultLibraryID);
- search.key = xmlSearch.@key.toString();
- search.dateAdded = xmlSearch.@dateAdded.toString();
- search.dateModified = xmlSearch.@dateModified.toString();
+ search.libraryID = _getLibraryID(searchNode.getAttribute('libraryID'), defaultLibraryID);
+ search.key = searchNode.getAttribute('key');
+ search.dateAdded = searchNode.getAttribute('dateAdded');
+ search.dateModified = searchNode.getAttribute('dateModified');
}
- search.name = xmlSearch.@name.toString();
+ search.name = searchNode.getAttribute('name');
var conditionID = -1;
// Search conditions
- for each(var condition in xmlSearch.condition) {
- conditionID = parseInt(condition.@id);
- var name = condition.@condition.toString();
- var mode = condition.@mode.toString();
+ var conditions = searchNode.getElementsByTagName('condition');
+ for each(var condition in conditions) {
+ conditionID = parseInt(condition.getAttribute('id'));
+ var name = condition.getAttribute('condition');
+ var mode = condition.getAttribute('mode');
if (mode) {
name = name + '/' + mode;
}
@@ -4365,17 +4369,17 @@ Zotero.Sync.Server.Data = new function() {
search.updateCondition(
conditionID,
name,
- condition.@operator.toString(),
- condition.@value.toString(),
- !!condition.@required.toString()
+ condition.getAttribute('operator'),
+ condition.getAttribute('value'),
+ !!condition.getAttribute('required')
);
}
else {
var newID = search.addCondition(
name,
- condition.@operator.toString(),
- condition.@value.toString(),
- !!condition.@required.toString()
+ condition.getAttribute('operator'),
+ condition.getAttribute('value'),
+ !!condition.getAttribute('required')
);
if (newID != conditionID) {
throw ("Search condition ids not contiguous in Zotero.Sync.Server.xmlToSearch()");
@@ -4393,36 +4397,38 @@ Zotero.Sync.Server.Data = new function() {
}
- function tagToXML(tag) {
- var xml = ;
- xml.@libraryID = tag.libraryID ? tag.libraryID : Zotero.libraryID;
- xml.@key = tag.key;
- xml.@name = _xmlize(tag.name);
+ this.tagToXML = function (tag, doc) {
+ var tagElem = doc.createElement('tag');
+ tagElem.setAttribute('libraryID', tag.libraryID ? tag.libraryID : Zotero.libraryID);
+ tagElem.setAttribute('key', tag.key);
+ tagElem.setAttribute('name', _xmlize(tag.name));
if (tag.type) {
- xml.@type = tag.type;
+ tagElem.setAttribute('type', tag.type);
}
- xml.@dateAdded = tag.dateAdded;
- xml.@dateModified = tag.dateModified;
+ tagElem.setAttribute('dateAdded', tag.dateAdded);
+ tagElem.setAttribute('dateModified', tag.dateModified);
var linkedItems = tag.getLinkedItems();
if (linkedItems) {
var linkedItemKeys = [];
for each(var linkedItem in linkedItems) {
linkedItemKeys.push(linkedItem.key);
}
- xml.items = linkedItemKeys.join(' ');
+ var itemsElem = doc.createElement('items');
+ itemsElem.appendChild(doc.createTextNode(linkedItemKeys.join(' ')));
+ tagElem.appendChild(itemsElem);
}
- return xml;
+ return tagElem;
}
/**
- * Convert E4X object into an unsaved Zotero.Tag
+ * Convert DOM node into an unsaved Zotero.Tag
*
- * @param object xmlTag E4X XML node with tag data
+ * @param object tagNode DOM XML node with tag data
* @param object tag (Optional) Existing Zotero.Tag to update
* @param bool skipPrimary (Optional) Ignore passed primary fields
*/
- function xmlToTag(xmlTag, tag, skipPrimary, defaultLibraryID, deletedItemKeys) {
+ this.xmlToTag = function (tagNode, tag, skipPrimary, defaultLibraryID, deletedItemKeys) {
if (!tag) {
tag = new Zotero.Tag;
}
@@ -4432,17 +4438,19 @@ Zotero.Sync.Server.Data = new function() {
}
if (!skipPrimary) {
- tag.libraryID = _getLibraryID(xmlTag.@libraryID.toString(), defaultLibraryID);
- tag.key = xmlTag.@key.toString();
- tag.dateAdded = xmlTag.@dateAdded.toString();
- tag.dateModified = xmlTag.@dateModified.toString();
+ tag.libraryID = _getLibraryID(tagNode.getAttribute('libraryID'), defaultLibraryID);
+ tag.key = tagNode.getAttribute('key');
+ tag.dateAdded = tagNode.getAttribute('dateAdded');
+ tag.dateModified = tagNode.getAttribute('dateModified');
}
- tag.name = xmlTag.@name.toString();
- tag.type = xmlTag.@type.toString() ? parseInt(xmlTag.@type) : 0;
+ tag.name = tagNode.getAttribute('name');
+ var type = tagNode.getAttribute('type');
+ tag.type = type ? parseInt(type) : 0;
- var keys = xmlTag.items.toString() ? xmlTag.items.toString().split(' ') : false;
+ var keys = _getFirstChildContent(tagNode, 'items');
if (keys) {
+ keys = keys.split(' ');
var ids = [];
for each(var key in keys) {
var item = Zotero.Items.getByLibraryAndKey(tag.libraryID, key);
@@ -4503,24 +4511,22 @@ Zotero.Sync.Server.Data = new function() {
/**
- * Convert E4X object into an unsaved Zotero.Group
+ * Convert DOM node into an unsaved Zotero.Group
*
- * @param object xmlGroup E4X XML node with group data
+ * @param object groupNode DOM XML node with group data
* @param object group (Optional) Existing Zotero.Group to update
*/
- this.xmlToGroup = function (xmlGroup, group) {
+ this.xmlToGroup = function (groupNode, group) {
if (!group) {
group = new Zotero.Group;
}
- Zotero.debug(xmlGroup.toXMLString());
-
- group.id = parseInt(xmlGroup.@id);
- group.libraryID = parseInt(xmlGroup.@libraryID);
- group.name = xmlGroup.@name.toString();
- group.editable = !!parseInt(xmlGroup.@editable);
- group.filesEditable = !!parseInt(xmlGroup.@filesEditable);
- group.description = xmlGroup.description.toString();
+ group.id = parseInt(groupNode.getAttribute('id'));
+ group.libraryID = parseInt(groupNode.getAttribute('libraryID'));
+ group.name = groupNode.getAttribute('name');
+ group.editable = !!parseInt(groupNode.getAttribute('editable'));
+ group.filesEditable = !!parseInt(groupNode.getAttribute('filesEditable'));
+ group.description = _getFirstChildContent(groupNode, 'description');
/*
var keys = xmlGroup.items.toString() ? xmlGroup.items.toString().split(' ') : false;
@@ -4544,12 +4550,18 @@ Zotero.Sync.Server.Data = new function() {
}
- this.relationToXML = function (relation) {
- return relation.toXML();
+ this.relationToXML = function (relation, doc) {
+ return relation.toXML(doc);
}
- this.xmlToRelation = function (xmlRelation) {
- return Zotero.Relations.xmlToRelation(xmlRelation);
+ this.xmlToRelation = function (relationNode) {
+ return Zotero.Relations.xmlToRelation(relationNode);
+ }
+
+
+ function _getFirstChildContent(node, childName) {
+ var elems = Zotero.Utilities.xpath(node, childName);
+ return elems.length ? elems[0].textContent : "";
}