コード例 #1
0
resultReturn.XMLAndCode = function (result, res) {
    if (result.length == 2) {
        res.code = '4.04';
        res.end(jstoxml.toXML({
            error: "Not Found"
        }));
    } else {
        res.code = '2.05';
        res.end(jstoxml.toXML(JSON.parse(result)));
    }
};
コード例 #2
0
ファイル: expedia.js プロジェクト: tifuivali/Edec
    // Normalize nested json to xml and then querystring it
    function _normalizeParamaters(parameters, request){
        if(typeof parameters !== 'object'){
            throw new Error("Paramaters must be passed in as an object");
        }

        // Extract customer from request object
        var customer = {
            customerSessionId : parameters.customerSessionId,
            customerIpAddress : parameters.customerIpAddress,
            customerUserAgent : parameters.customerUserAgent
        };
        delete(parameters.customerSessionId);
        delete(parameters.customerIpAddress);
        delete(parameters.customerUserAgent);

        customer = querystring.stringify(customer);

        var paramsAsString = customer +"&json&";
        if (sendAsREST){
            paramsAsString += querystring.stringify(parameters);
        }
        else {
            paramsAsString += querystring.stringify({"xml" : parser.toXML(parameters)});
        }
        return paramsAsString;
    }
コード例 #3
0
ファイル: service.js プロジェクト: haibinyu/upnpserver
	/**
	 *
	 */
	responseSoap(response, functionName, body, callback) {

		var jxml = {
			_name: "s:Envelope",
			_attrs: {
				xmlns: Xmlns.UPNP_SERVICE,
				"xmlns:s": Xmlns.SOAP_ENVELOPE,
				"s:encodingStyle": "http://schemas.xmlsoap.org/soap/encoding/"
			},
			_content: {
				"s:Body": body
			}
		};

		var xml = jstoxml.toXML(jxml, {
			header: true,
			indent: "",
			filter: xmlFilters
		});

		debug("responseSoap", "function=", functionName, "response=", xml);

		response.setHeader("Content-Type", "text/xml; charset=\"utf-8\"");

		response.end(xml, "utf8");

		callback(null);
	}
コード例 #4
0
 buildAcl: function () {
   return jstoxml.toXML({
     _name: 'AccessControlPolicy',
     _attrs: {'xmlns': 'http://doc.s3.amazonaws.com/2006-03-01'},
     _content: {
       Owner: {
         ID: 123,
         DisplayName: DISPLAY_NAME
       },
       AccessControlList: {
         Grant: {
           _name: 'Grantee',
           _attrs: {
             'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
             'xsi:type': 'CanonicalUser'
           },
           _content: {
             ID: 'abc',
             DisplayName: 'You'
           }
         },
         Permission: 'FULL_CONTROL'
       }
     }
   }, {
     header: true,
     indent: '  '
   });
 },
コード例 #5
0
ファイル: service.js プロジェクト: HendrikRoth/upnpserver
Service.prototype.responseSoap = function (response, functionName, body,
											callback) {

	var jxml = {
		_name : "s:Envelope",
		_attrs : {
			xmlns : "urn:schemas-upnp-org:service-1-0",
			"xmlns:s" : "http://schemas.xmlsoap.org/soap/envelope/",
			"s:encodingStyle" : "http://schemas.xmlsoap.org/soap/encoding/"
		},
		_content : {
			"s:Body" : body
		}
	};

	var xml = jstoxml.toXML(jxml, {
		header : true,
		indent : " "
	});

	logger.debug(functionName + ": Response=", xml);

	response.setHeader("Content-Type", "text/xml; charset=\"utf-8\"");
	response.end(xml, "UTF-8");

	return callback(null);
};
コード例 #6
0
                  }, function(error) {
                    if (error) {
                      return callback(error);
                    }

                    var didl = jstoxml.toXML(xmlDidl, {
                      header : false,
                      indent : "",
                      filter : xmlFilters
                    });

                    // console.log("didl=", didl);

                    self.responseSoap(response, "Browse", {
                      _name : "u:BrowseResponse",
                      _attrs : {
                        "xmlns:u" : self.type
                      },
                      _content : {
                        Result : didl,
                        NumberReturned : count,
                        TotalMatches : total,
                        UpdateID : (item.id)
                            ? item.itemUpdateId : self.systemUpdateId
                      }
                    }, function(error) {
                      if (error) {
                        return callback(error);
                      }

                      // debug("CDS: Browse end " +
                      // containerId);
                      callback(null);
                    });
                  });
コード例 #7
0
ファイル: rss.js プロジェクト: blmarket/watchitlater
  model.rsslist(function(err, res) {
    if(err) callback(err);

    var ret = {
      _name: 'rss',
      _attrs: {
        'xmlns:itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd',
        version: '2.0'
      },
      _content: {
        channel: [
          {title: 'my favourites'},
          {link: 'black market'},
          {description: "oh yes I don't know about copyrights"},
          {lastBuildDate: function() { return new Date(); }},
          {pubDate: function() { return new Date(); }},
          {language: 'ko_KR'},
          {
            _name: 'itunes:image',
            _attrs: {
              href: 'http://naver.com/favicon.ico'
            }
          }
        ]
      }
    };

    var target = ret._content.channel;
    (function() {
      if(!res) return;
      var length = res.length;
      for(var i=0;i<length;i++) {
        var obj = JSON.parse(res[i]);
        var tmp = obj.key.split(':');
        var category = tmp[0];
        var id = tmp[1];
        var type = obj.type || 'video/x-flv';
        target[target.length] = {
          item: [
            { title: obj.title },
            {
              _name: 'enclosure',
              _attrs: {
                url: 'http://192.168.0.4:3279/get/' + obj.key,
                type: type
              }
            },
            { description: obj.desc },
            { pubDate: function() {
              return new Date();
            }}
          ]
        }
      }
    })();

    callback(null, jstoxml.toXML(ret, {header: true, indent: '  '}));
  });
コード例 #8
0
ファイル: service.js プロジェクト: jkso/ht5streamer
Service.prototype.sendEvent = function(eventName, xmlContent) {
  var eventKey = this._eventKey++;

  // logger.debug("Send event xmlContent=", xmlContent);

  var clients = this._eventClients;

  if (!Object.keys(clients).length) {
    return;
  }

  var clientsCopy = [];
  for ( var k in clients) {
    clientsCopy.push(clients[k]);
  }

  var xml = jstoxml.toXML(xmlContent, {
    header : true,
    indent : " ",
    filter : xmlFilters
  });

  // logger.info("Send event ", xml, " to " + clientsCopy.length + " clients");

  var self = this;
  Async.eachLimit(clientsCopy, EVENT_CLIENTS_PROCESSOR_LIMIT, function(client,
      callback) {
    if (client.deleted || !client.url) {
      return;
    }

    var url = URL.parse(client.url);

    try {
      var req = http.request({
        hostname : url.hostname,
        port : url.port,
        method : "NOTIFY",
        path : url.path,
        headers : {
          server : self.upnpServer.serverName,
          "Content-Type" : "text/xml; charset=\"utf-8\"",
          NT : "upnp:event",
          NTS : eventName,
          SEQ : eventKey,
          SID : "uuid:" + client.uuid
        }
      });

      req.write(xml);
      req.end();
    } catch (x) {
      logger.error("Can not send http request", x);
    }
  });

};
コード例 #9
0
ファイル: routes.js プロジェクト: Platos-Cave/neuralquest
 app.get('/sitemap.xml', function(req, res) {
     var sitemapObj = jstoxml.toXML({
         _name: 'urlset',
         _attrs: {
             xmlns: "http://www.sitemaps.org/schemas/sitemap/0.9"
         },
         _content: [
             {url: {
                 loc: 'http://neuralquest.org#.575d4c3f2cf3d6dc3ed83146...575d4c3f2cf3d6dc3ed83148.575d4c3f2cf3d6dc3ed83147..0'
             }},
             {url: {
                 loc: 'http://neuralquest.org#.575d4c3f2cf3d6dc3ed83146...575d4c3f2cf3d6dc3ed83148.575d4c3f2cf3d6dc3ed83147..0'
             }}
         ]
     }, {header: true, indent: '  '});
     var sitemapXml = jstoxml.toXML(sitemapObj, true, '  ');
     res.header('Content-Type', 'application/xml');
     res.send( sitemapXml );
 });
コード例 #10
0
 buildBucketQuery: function (options, items) {
   var xml = {
     _name: 'ListAllMyBucketsResult',
     _attrs: {'xmlns': 'http://doc.s3.amazonaws.com/2006-03-01'},
     _content: buildQueryContentXML(items, options)
   };
   return jstoxml.toXML(xml, {
     header: true,
     indent: '  '
   });
 },
コード例 #11
0
 buildCopyObject: function (item) {
   return jstoxml.toXML({
     CopyObjectResult: {
       LastModified: item.modifiedDate,
       ETag: item.md5
     }
   }, {
     header: true,
     indent: '  '
   });
 }
コード例 #12
0
 buildObjectsDeleted: function (keys) {
   return jstoxml.toXML({
     _name: 'DeleteResult',
     _attrs: {xmlns: 'http://s3.amazonaws.com/doc/2006-03-01/'},
     _content: keys.map(function (k) {
       return {Deleted: {Key: k}};
     })
   }, {
     header: true,
     indent: '  '
   });
 },
コード例 #13
0
 buildError: function (code, message) {
   return jstoxml.toXML({
     Error: {
       Code: code,
       Message: message,
       RequestId: 1
     }
   }, {
     header: true,
     indent: '  '
   });
 },
コード例 #14
0
ファイル: dispatcher.js プロジェクト: AmeenAhmed/nails
		this.toXML = function() {
			var schema = require(process.cwd() + '/db/' + this.table_name + '_schema.js').schema;

			var obj = {};

			for(var attr in schema) {
				obj[attr] = this[attr];
			}
			var jstoxml = require('jstoxml');
			return jstoxml.toXML(obj);
			
		}
コード例 #15
0
ファイル: service.js プロジェクト: HendrikRoth/upnpserver
Service.prototype.processScpdRequest = function (request, response, path,
												  callback) {
	var xml = jstoxml.toXML(this._descJXML, {
		header : true,
		indent : " "
	});
	logger.debug("SCPD: Response=", xml);
	response.setHeader("Content-Type", "text/xml; charset=\"utf-8\"");
	response.end(xml, "UTF-8");

	return callback(null, true);
};
コード例 #16
0
ファイル: cli.js プロジェクト: siparker/YellowLabTools
        then(function(data) {

            debug('Success');
            switch(cli.flags.reporter) {
                case 'xml':
                    console.log(jstoxml.toXML(data, {indent: '  '}));
                    break;
                default:
                    console.log(JSON.stringify(data, null, 2));
            }

        }).fail(function(err) {
コード例 #17
0
 buildKeyNotFound: function (key) {
   return jstoxml.toXML({
     Error: {
       Code: 'NoSuchKey',
       Message: 'The specified key does not exist',
       Resource: key,
       RequestId: 1
     }
   }, {
     header: true,
     indent: '  '
   });
 },
コード例 #18
0
 buildBucketNotFound: function (bucketName) {
   return jstoxml.toXML({
     Error: {
       Code: 'NoSuchBucket',
       Message: 'The resource you requested does not exist',
       Resource: bucketName,
       RequestId: 1
     }
   }, {
     header: true,
     indent: '  '
   });
 },
コード例 #19
0
 buildBucketNotEmpty: function (bucketName) {
   return jstoxml.toXML({
     Error: {
       Code: 'BucketNotEmpty',
       Message: 'The bucket your tried to delete is not empty',
       Resource: bucketName,
       RequestId: 1,
       HostId: 2
     }
   }, {
     header: true,
     indent: '  '
   });
 },
コード例 #20
0
ファイル: service.js プロジェクト: haibinyu/upnpserver
	processScpdRequest(request, response, callback) {
		var xml = jstoxml.toXML(this._descJXML, {
			header: true,
			indent: " ",
			filter: xmlFilters
		});
		// logger.debug("SCPD: Response=", xml);
		response.setHeader("Content-Type", "text/xml; charset=\"utf-8\"");
		response.end(xml, "UTF-8");

		debug("processScpdRequest", "SCDP request returns", xml);

		return callback(null, true);
	}
コード例 #21
0
    item.toJXML(repositoryRequest, function(error, itemXML) {
      if (error) {
        return callback(error);
      }

      var xmlDidl = {
        _name : "DIDL-Lite",
        _attrs : {
          "xmlns" : "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/",
          "xmlns:dc" : "http://purl.org/dc/elements/1.1/",
          "xmlns:upnp" : "urn:schemas-upnp-org:metadata-1-0/upnp/"
        },
        _content : itemXML
      };

      if (self.upnpServer.dlnaSupport) {
        xmlDidl._attrs["xmlns:dlna"] = "urn:schemas-dlna-org:metadata-1-0/";
      }

      var didl = jstoxml.toXML(xmlDidl, {
        header : false,
        indent : " ",
        filter : xmlFilters
      });

      // console.log("didl=", didl);

      self.responseSoap(response, "Browse", {
        _name : "u:BrowseResponse",
        _attrs : {
          "xmlns:u" : self.type
        },
        _content : {
          Result : didl,
          NumberReturned : 1,
          TotalMatches : 1,
          UpdateID : (item.id)
              ? item.itemUpdateId
              : self.systemUpdateId
        }
      }, function(error) {
        if (error) {
          return callback(error);
        }

        // logger.debug("CDS: Browse end " + containerId);
        callback(null);
      });
    });
コード例 #22
0
ファイル: upnpServer.js プロジェクト: jkso/ht5streamer
    return this.toJXML(request, function(error, xmlObject) {
      if (error) {
        return callback(error);
      }

      var xml = jstoxml.toXML(xmlObject, {
        header : true,
        indent : " ",
        filter : xmlFilters
      });

      // logger.verbose("Request description path: " + xml);
      response.setHeader("Content-Type", "text/xml; charset=\"utf-8\"");

      response.end(xml, "UTF-8");
      return callback(null, true);
    });
コード例 #23
0
ファイル: index.js プロジェクト: DelvarWorld/react-to-jsx
var reactToJsx = function (component, options) {
  var defaults = {
    indent: '\t',
    includeNull: true,
    exclude: []
  };

  var config = _.extend({}, defaults, options);

  var componentXml = jstoxml.toXML(componentToJson(component, config), {
    indent: config.indent
  });

  componentXml = componentXml
    .replace(/"LITERAL!/g, '{')
    .replace(/!LITERAL"/g, '}')

  var componentArray = componentXml.split('\n');

  componentArray = _.map(componentArray, function (line) {
    var attributeMatcher = /\s+(?=\S*=)/g;

    if ((line.match(attributeMatcher) || []).length < 2) {
      return line;
    }

    var indentRegex = new RegExp(config.indent, 'g');

    var indentDepth = (line.match(indentRegex) || []).length;
    var newlineString = '\n' + config.indent;

    for (var i = 0; i < indentDepth; i++) {
      newlineString += config.indent;
    }

    line = line.replace(attributeMatcher, newlineString);

    return line;
  });

  componentXml = componentArray.join('\n');

  return componentXml;
};
コード例 #24
0
ファイル: web.js プロジェクト: rbirkby/msdownloads
	  $(function () {
	    var items = $("td.descTD");
	    itemCount = items.length;
	    console.log("got " + itemCount + " items");

	    items.each(function(index, item) {
	      feed._content.channel.push({
		item: {
		  title:encode($("div.link a", item).text()),
		  link:"http://www.microsoft.com" + $("div.link a", item).attr("href") + "#tm",
		  description:encode($("div.description", item).text())
		}
	      });
	    });
	    content = poweredBy + jstoxml.toXML(feed, false, '');
	    console.log("rss output updated");
	  
	    setTimeout(function() {window.close();}, 500);
	  });
コード例 #25
0
 buildBuckets: function (buckets) {
   return jstoxml.toXML({
     _name: 'ListAllMyBucketsResult',
     _attrs: {'xmlns': 'http://doc.s3.amazonaws.com/2006-03-01'},
     _content: {
       Owner: {
         ID: 123,
         DisplayName: DISPLAY_NAME
       },
       Buckets: _.map(buckets, function (bucket) {
         return {
           Bucket: {
             Name: bucket.name,
             CreationDate: bucket.creationDate.toISOString()
           }
         };
       })
     }
   }, {
     header: true,
     indent: '  '
   });
 },
コード例 #26
0
module.exports  = function (params, callback) {

  var assemble  = params.assemble;
  var grunt     = params.grunt;
  var pages     = assemble.options.pages;
  var options   = assemble.options.sitemap || {};
  var sitemap   = [];
  var robots    = [];
  var exclusion = ['404'];
  var pkg       = grunt.file.readJSON('package.json');

  options.homepage = options.homepage || pkg.homepage;
  options.robot = options.robot !== false;
  options.changefreq = options.changefreq || 'weekly';
  options.priority = (options.priority || 0.5).toString();
  options.addhome = options.addhome || true;
  options.omit_index = options.omit_index || true;
  options.force_exclusion = options.force_exclusion || true;
  options.dest = options.dest || path.dirname(pages[0].dest);


  // Only write if it actually changed.
  var write = function (file, content) {
    var msg;
    var old = grunt.file.exists(file) ? grunt.file.read(file) : '';

    if (old !== content) {
      grunt.file.write(file, content);
      msg = 'Created '.yellow + file.cyan;
    } else {
      msg = 'Keeping '.yellow + file.cyan;
    }
    return grunt.verbose.ok(msg);
  };

  // Return the relative destination if the option is enabled
  var getExternalFilePath = function (relativedest, file) {
    if(relativedest === true) {
      relativedest = options.dest;
    }
    return (relativedest ? file.dest.replace(relativedest + "/", "") : file.dest );
  };

  var url = options.homepage;
  var relativedest = options.relativedest;

  //Push homepage url if enabled
  if (options.addhome === true) {
    sitemap.push({
      url: {
        loc: url,
        lastmod: (new Date()).toISOString(),
        changefreq: options.changefreq,
        priority: options.priority
      }
    });
  }

  //Build master exlusion list
  if (!_.isUndefined(options.exclude)) {
    exclusion = _.union([], exclusion, options.exclude || []);
  }


  var fex = _.filter(exclusion, function(e){ return e.indexOf('force:') !== -1; });

  if (options.force_exclusion) {
    async.forEach(fex, function (e, next) {
       robots.push('Disallow: /' + e.replace('force:',''));

      next();
    }, callback());
  }//Non-file exclusions should be added as-is if prefixed with 'force:'


  async.forEach(pages, function (file, next) {

    var date = file.data.updated || file.data.date || new Date();
    var changefreq = file.data.changefreq || options.changefreq;
    var priority = file.data.priority || options.priority;

    if (exclusion.indexOf(file.basename) !== -1 ||
        grunt.file.isMatch({srcBase: options.dest}, exclusion, file.dest)) {
      robots.push('Disallow: /' + getExternalFilePath(relativedest, file));
      return;
    }

    if (options.omit_index || file.basename === 'index') {
      return;
    }//omit index.html from sitemap

    sitemap.push({
      url: {
        loc: url + '/' + getExternalFilePath(relativedest, file),
        lastmod: date.toISOString(),
        changefreq: changefreq,
        priority: priority
      }
    });

    next();
  }, callback());

  var result = xml.toXML({
    _name: 'urlset',
    _attrs: {
      xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9'
    },
    _content: sitemap
  }, {header: true, indent: '  '});



  var sitemapDest = options.dest + '/sitemap.xml';
  write(sitemapDest, result);

  if (options.robot) {
    var sitemapFile = {dest: url + "/sitemap.xml"};
    var robot = "User-agent: *\n";

    robot += robots.join('\n') + '\n\n';

    robot += "Sitemap: " + getExternalFilePath(relativedest, sitemapFile);
    robot += "\n";

    var robotpDest = options.dest + '/robots.txt';
    write(robotpDest, robot);
  }

};
コード例 #27
0
ファイル: App.js プロジェクト: aversh32/bg
 xml: function (data) {
     return xml.toXML({response: data});
 }
コード例 #28
0
ファイル: index.js プロジェクト: jjgod/hexo-plugins
extend.generator.register(function(locals, render, callback){
  var config = hexo.config;

  var content = [
    {title: '<![CDATA[' + config.title + ']]>'},
    {
      _name: 'link',
      _attrs: {
        href: config.url + '/atom.xml',
        rel: 'self'
      }
    },
    {
      _name: 'link',
      _attrs: {
        href: config.url
      }
    },
    {updated: new Date().toISOString()},
    {id: config.url + '/'},
    {author:
      {
        name: '<![CDATA[' + config.author + ']]>'
      }
    },
    {
      _name: 'generator',
      _attrs: {
        uri: 'http://zespia.tw/hexo'
      },
      _content: 'Hexo'
    }
  ];

  if (config.email) content[5].author.email = '<![CDATA[' + config.email + ']]>';
  if (config.subtitle) content.splice(1, 0, {subtitle: '<![CDATA[' + config.subtitle + ']]>'});

  locals.posts.limit(20).each(function(item){
    var entry = [
      {
        _name: 'title',
        _attrs: {
          type: 'html'
        },
        _content: '<![CDATA[' + item.title + ']]>'
      },
      {
        _name: 'link',
        _attrs: {
          href: item.permalink
        }
      },
      {id: item.permalink},
      {published: item.date.toDate().toISOString()},
      {updated: item.updated.toDate().toISOString()},
      {
        _name: 'content',
        _attrs: {
          type: 'html'
        },
        _content: '<![CDATA[' + item.content + ']]>'
      },
    ];

    if (item.tags){
      var tags = [];

      item.tags.forEach(function(tag){
        tags.push({
          _name: 'category',
          _attrs: {
            scheme: tag.permalink,
            term: tag.name
          }
        });
      });

      entry = [].concat(entry, tags);
    }

    content.push({entry: entry});
  });

  var result = xml.toXML({
    _name: 'feed',
    _attrs: {
      xmlns: 'http://www.w3.org/2005/Atom'
    },
    _content: content
  }, {header: true, indent: '  '});

  route.set('atom.xml', result);
  callback();
});
コード例 #29
0
ファイル: service.js プロジェクト: haibinyu/upnpserver
	sendEvent(eventName, xmlContent) {
		var eventKey = this._eventKey++;

		// if (debugEvent.enabled) {
		// debugEvent("Send event xmlContent=", xmlContent);
		// }

		var clients = this._eventClients;

		if (!Object.keys(clients).length) {

			var xml2 = jstoxml.toXML(xmlContent, {
				header: true,
				indent: " ",
				filter: xmlFilters
			});

			debugEvent("sendEvent", "Send event NO client => ", xml2);

			return;
		}

		var clientsCopy = [];
		for (var k in clients) {
			clientsCopy.push(clients[k]);
		}

		var xml = jstoxml.toXML(xmlContent, {
			header: true,
			indent: " ",
			filter: xmlFilters
		});

		debugEvent("sendEvent", "send", xml, "to", clientsCopy.length, "clients");

		Async.eachLimit(clientsCopy, EVENT_CLIENTS_PROCESSOR_LIMIT, (client,
																																 callback) => {
			if (client.deleted || !client.url) {
				callback();
				return;
			}

			var url = URL.parse(client.url);

			var done = false;
			try {
				var req = http.request({
					hostname: url.hostname,
					port: url.port,
					method: "NOTIFY",
					path: url.path,
					headers: {
						server: this.upnpServer.serverName,
						"Content-Type": "text/xml; charset=\"utf-8\"",
						NT: "upnp:event",
						NTS: eventName,
						SEQ: eventKey,
						SID: "uuid:" + client.uuid
					}
				});

				req.on("error", (e) => {
					if (!client.deleted) {
						logger.error(
							"ERROR: Remove client '" + client.url + "' from list. [ServiceId=" + this.id + "]", e);

						client.deleted = true;
					}

					if (done) {
						return;
					}
					done = true;
					callback();
				});

				req.write(xml);
				req.end(() => {
					if (done) {
						return;
					}
					done = true;
					callback();
				});

			} catch (x) {
				logger.error("Can not send http request [ServiceId=" + this.id + "]", x, x.stack);

				client.deleted = true;

				if (!done) {
					done = true;
					callback();
				}
			}
		});
	}
コード例 #30
0
module.exports  = function (params, callback) {
  
  var assemble  = params.assemble;
  var grunt     = params.grunt;
  var pages     = assemble.options.pages;
  var options   = assemble.options.sitemap || {};
  var dest      = path.dirname(pages[0].dest);
  var sitemap   = [];
  var robots    = [];
  var exclusion = ['404'];
  var pkg       = grunt.file.readJSON('package.json');

  options.homepage = options.homepage || pkg.homepage;
  options.robot = options.robot || true;
  options.changefreq = options.changefreq || 'weekly';
  options.priority = (options.priority || 0.5).toString();
  options.relativedest = options.relativedest || false;


  // Only write if it actually changed.
  var write = function(file, content) {
    var msg;
    var old = grunt.file.exists(file) ? grunt.file.read(file) : '';

    if (old !== content) {
      grunt.file.write(file, content);
      msg = 'Created '.yellow + file.cyan;
    } else {
      msg = 'Keeping '.yellow + file.cyan;
    }
    return grunt.verbose.ok(msg);
  };

  async.forEach(pages, function (file, next) {

    if(!_.isUndefined(options.exclude)) {
      exclusion = _.union([], exclusion, options.exclude || []);
    }

    var url = options.homepage;
    var date = file.data.updated || file.data.date || new Date();
    var changefreq = options.changefreq;
    var priority = options.priority;
    var relativedest = options.relativedest;
    
    if(exclusion.indexOf(file.basename) !== -1) {
      robots.push('Disallow: /' + file.dest);
      return;
    }

    sitemap.push({
      url: {
        loc: url + '/' + (relativedest ? file.dest.replace(file.filePair.orig.dest+"/","") : file.dest ),
        lastmod: date.toISOString(),
        changefreq: changefreq,
        priority: priority
      }
    });

  next();
  }, callback());

  var result = xml.toXML({
    _name: 'urlset',
    _attrs: {
      xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9'
    },
    _content: sitemap
  }, {header: true, indent: '  '});

  

  var sitemapDest = dest + '/sitemap.xml';
  write(sitemapDest, result);

  if (options.robot) {
    var robot = "User-agent: *\n\n";

    _.forEach(robots, function(item) {
      robot += item + '\n';
    });

    var robotpDest = dest + '/robots.txt';
    write(robotpDest, robot);
  }
  
};