정민혁

백과사전 구현시도(실패), 네이버 트랜드검색api를 대신 도입- response 값 parsing에 문제가 있어서 카카오톡으로는 response값을 그대로 출력하도록 설정

Showing 118 changed files with 3757 additions and 0 deletions
sudo: true
language: node_js
node_js:
- 8
script: npm run coveralls
Copyright (c) Felix Böhm
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
var encode = require("./lib/encode.js"),
decode = require("./lib/decode.js");
exports.decode = function(data, level) {
return (!level || level <= 0 ? decode.XML : decode.HTML)(data);
};
exports.decodeStrict = function(data, level) {
return (!level || level <= 0 ? decode.XML : decode.HTMLStrict)(data);
};
exports.encode = function(data, level) {
return (!level || level <= 0 ? encode.XML : encode.HTML)(data);
};
exports.encodeXML = encode.XML;
exports.encodeHTML4 = exports.encodeHTML5 = exports.encodeHTML = encode.HTML;
exports.decodeXML = exports.decodeXMLStrict = decode.XML;
exports.decodeHTML4 = exports.decodeHTML5 = exports.decodeHTML = decode.HTML;
exports.decodeHTML4Strict = exports.decodeHTML5Strict = exports.decodeHTMLStrict = decode.HTMLStrict;
exports.escape = encode.escape;
var entityMap = require("../maps/entities.json"),
legacyMap = require("../maps/legacy.json"),
xmlMap = require("../maps/xml.json"),
decodeCodePoint = require("./decode_codepoint.js");
var decodeXMLStrict = getStrictDecoder(xmlMap),
decodeHTMLStrict = getStrictDecoder(entityMap);
function getStrictDecoder(map) {
var keys = Object.keys(map).join("|"),
replace = getReplacer(map);
keys += "|#[xX][\\da-fA-F]+|#\\d+";
var re = new RegExp("&(?:" + keys + ");", "g");
return function(str) {
return String(str).replace(re, replace);
};
}
var decodeHTML = (function() {
var legacy = Object.keys(legacyMap).sort(sorter);
var keys = Object.keys(entityMap).sort(sorter);
for (var i = 0, j = 0; i < keys.length; i++) {
if (legacy[j] === keys[i]) {
keys[i] += ";?";
j++;
} else {
keys[i] += ";";
}
}
var re = new RegExp("&(?:" + keys.join("|") + "|#[xX][\\da-fA-F]+;?|#\\d+;?)", "g"),
replace = getReplacer(entityMap);
function replacer(str) {
if (str.substr(-1) !== ";") str += ";";
return replace(str);
}
//TODO consider creating a merged map
return function(str) {
return String(str).replace(re, replacer);
};
})();
function sorter(a, b) {
return a < b ? 1 : -1;
}
function getReplacer(map) {
return function replace(str) {
if (str.charAt(1) === "#") {
if (str.charAt(2) === "X" || str.charAt(2) === "x") {
return decodeCodePoint(parseInt(str.substr(3), 16));
}
return decodeCodePoint(parseInt(str.substr(2), 10));
}
return map[str.slice(1, -1)];
};
}
module.exports = {
XML: decodeXMLStrict,
HTML: decodeHTML,
HTMLStrict: decodeHTMLStrict
};
var decodeMap = require("../maps/decode.json");
module.exports = decodeCodePoint;
// modified version of https://github.com/mathiasbynens/he/blob/master/src/he.js#L94-L119
function decodeCodePoint(codePoint) {
if ((codePoint >= 0xd800 && codePoint <= 0xdfff) || codePoint > 0x10ffff) {
return "\uFFFD";
}
if (codePoint in decodeMap) {
codePoint = decodeMap[codePoint];
}
var output = "";
if (codePoint > 0xffff) {
codePoint -= 0x10000;
output += String.fromCharCode(((codePoint >>> 10) & 0x3ff) | 0xd800);
codePoint = 0xdc00 | (codePoint & 0x3ff);
}
output += String.fromCharCode(codePoint);
return output;
}
var inverseXML = getInverseObj(require("../maps/xml.json")),
xmlReplacer = getInverseReplacer(inverseXML);
exports.XML = getInverse(inverseXML, xmlReplacer);
var inverseHTML = getInverseObj(require("../maps/entities.json")),
htmlReplacer = getInverseReplacer(inverseHTML);
exports.HTML = getInverse(inverseHTML, htmlReplacer);
function getInverseObj(obj) {
return Object.keys(obj)
.sort()
.reduce(function(inverse, name) {
inverse[obj[name]] = "&" + name + ";";
return inverse;
}, {});
}
function getInverseReplacer(inverse) {
var single = [],
multiple = [];
Object.keys(inverse).forEach(function(k) {
if (k.length === 1) {
single.push("\\" + k);
} else {
multiple.push(k);
}
});
//TODO add ranges
multiple.unshift("[" + single.join("") + "]");
return new RegExp(multiple.join("|"), "g");
}
var re_nonASCII = /[^\0-\x7F]/g,
re_astralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
function singleCharReplacer(c) {
return (
"&#x" +
c
.charCodeAt(0)
.toString(16)
.toUpperCase() +
";"
);
}
function astralReplacer(c) {
// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
var high = c.charCodeAt(0);
var low = c.charCodeAt(1);
var codePoint = (high - 0xd800) * 0x400 + low - 0xdc00 + 0x10000;
return "&#x" + codePoint.toString(16).toUpperCase() + ";";
}
function getInverse(inverse, re) {
function func(name) {
return inverse[name];
}
return function(data) {
return data
.replace(re, func)
.replace(re_astralSymbols, astralReplacer)
.replace(re_nonASCII, singleCharReplacer);
};
}
var re_xmlChars = getInverseReplacer(inverseXML);
function escapeXML(data) {
return data
.replace(re_xmlChars, singleCharReplacer)
.replace(re_astralSymbols, astralReplacer)
.replace(re_nonASCII, singleCharReplacer);
}
exports.escape = escapeXML;
{"0":65533,"128":8364,"130":8218,"131":402,"132":8222,"133":8230,"134":8224,"135":8225,"136":710,"137":8240,"138":352,"139":8249,"140":338,"142":381,"145":8216,"146":8217,"147":8220,"148":8221,"149":8226,"150":8211,"151":8212,"152":732,"153":8482,"154":353,"155":8250,"156":339,"158":382,"159":376}
\ No newline at end of file
This diff is collapsed. Click to expand it.
{"Aacute":"\u00C1","aacute":"\u00E1","Acirc":"\u00C2","acirc":"\u00E2","acute":"\u00B4","AElig":"\u00C6","aelig":"\u00E6","Agrave":"\u00C0","agrave":"\u00E0","amp":"&","AMP":"&","Aring":"\u00C5","aring":"\u00E5","Atilde":"\u00C3","atilde":"\u00E3","Auml":"\u00C4","auml":"\u00E4","brvbar":"\u00A6","Ccedil":"\u00C7","ccedil":"\u00E7","cedil":"\u00B8","cent":"\u00A2","copy":"\u00A9","COPY":"\u00A9","curren":"\u00A4","deg":"\u00B0","divide":"\u00F7","Eacute":"\u00C9","eacute":"\u00E9","Ecirc":"\u00CA","ecirc":"\u00EA","Egrave":"\u00C8","egrave":"\u00E8","ETH":"\u00D0","eth":"\u00F0","Euml":"\u00CB","euml":"\u00EB","frac12":"\u00BD","frac14":"\u00BC","frac34":"\u00BE","gt":">","GT":">","Iacute":"\u00CD","iacute":"\u00ED","Icirc":"\u00CE","icirc":"\u00EE","iexcl":"\u00A1","Igrave":"\u00CC","igrave":"\u00EC","iquest":"\u00BF","Iuml":"\u00CF","iuml":"\u00EF","laquo":"\u00AB","lt":"<","LT":"<","macr":"\u00AF","micro":"\u00B5","middot":"\u00B7","nbsp":"\u00A0","not":"\u00AC","Ntilde":"\u00D1","ntilde":"\u00F1","Oacute":"\u00D3","oacute":"\u00F3","Ocirc":"\u00D4","ocirc":"\u00F4","Ograve":"\u00D2","ograve":"\u00F2","ordf":"\u00AA","ordm":"\u00BA","Oslash":"\u00D8","oslash":"\u00F8","Otilde":"\u00D5","otilde":"\u00F5","Ouml":"\u00D6","ouml":"\u00F6","para":"\u00B6","plusmn":"\u00B1","pound":"\u00A3","quot":"\"","QUOT":"\"","raquo":"\u00BB","reg":"\u00AE","REG":"\u00AE","sect":"\u00A7","shy":"\u00AD","sup1":"\u00B9","sup2":"\u00B2","sup3":"\u00B3","szlig":"\u00DF","THORN":"\u00DE","thorn":"\u00FE","times":"\u00D7","Uacute":"\u00DA","uacute":"\u00FA","Ucirc":"\u00DB","ucirc":"\u00FB","Ugrave":"\u00D9","ugrave":"\u00F9","uml":"\u00A8","Uuml":"\u00DC","uuml":"\u00FC","Yacute":"\u00DD","yacute":"\u00FD","yen":"\u00A5","yuml":"\u00FF"}
\ No newline at end of file
{"amp":"&","apos":"'","gt":">","lt":"<","quot":"\""}
{
"_from": "entities@^1.1.1",
"_id": "entities@1.1.2",
"_inBundle": false,
"_integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
"_location": "/entities",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "entities@^1.1.1",
"name": "entities",
"escapedName": "entities",
"rawSpec": "^1.1.1",
"saveSpec": null,
"fetchSpec": "^1.1.1"
},
"_requiredBy": [
"/rss-parser"
],
"_resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
"_shasum": "bdfa735299664dfafd34529ed4f8522a275fea56",
"_spec": "entities@^1.1.1",
"_where": "C:\\Users\\정민채\\Desktop\\TermProject\\2017104024정민혁KakaoBot\\node_modules\\rss-parser",
"author": {
"name": "Felix Boehm",
"email": "me@feedic.com"
},
"bugs": {
"url": "https://github.com/fb55/entities/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Encode & decode XML/HTML entities with ease",
"devDependencies": {
"coveralls": "*",
"istanbul": "*",
"jshint": "2",
"mocha": "^5.0.1",
"mocha-lcov-reporter": "*"
},
"directories": {
"test": "test"
},
"homepage": "https://github.com/fb55/entities#readme",
"jshintConfig": {
"eqeqeq": true,
"freeze": true,
"latedef": "nofunc",
"noarg": true,
"nonbsp": true,
"quotmark": "double",
"undef": true,
"unused": true,
"trailing": true,
"eqnull": true,
"proto": true,
"smarttabs": true,
"node": true,
"globals": {
"describe": true,
"it": true
}
},
"keywords": [
"html",
"xml",
"entity",
"decoding",
"encoding"
],
"license": "BSD-2-Clause",
"main": "./index.js",
"name": "entities",
"prettier": {
"tabWidth": 4
},
"repository": {
"type": "git",
"url": "git://github.com/fb55/entities.git"
},
"scripts": {
"coveralls": "npm run lint && npm run lcov && (cat coverage/lcov.info | coveralls || exit 0)",
"lcov": "istanbul cover _mocha --report lcovonly -- -R spec",
"lint": "jshint index.js lib/*.js test/*.js",
"test": "mocha && npm run lint"
},
"version": "1.1.2"
}
# entities [![NPM version](http://img.shields.io/npm/v/entities.svg)](https://npmjs.org/package/entities) [![Downloads](https://img.shields.io/npm/dm/entities.svg)](https://npmjs.org/package/entities) [![Build Status](http://img.shields.io/travis/fb55/entities.svg)](http://travis-ci.org/fb55/entities) [![Coverage](http://img.shields.io/coveralls/fb55/entities.svg)](https://coveralls.io/r/fb55/entities)
En- & decoder for XML/HTML entities.
## How to…
### …install `entities`
npm i entities
### …use `entities`
```javascript
var entities = require("entities");
//encoding
entities.encodeXML("&#38;"); // "&amp;#38;"
entities.encodeHTML("&#38;"); // "&amp;&num;38&semi;"
//decoding
entities.decodeXML("asdf &amp; &#xFF; &#xFC; &apos;"); // "asdf & ÿ ü '"
entities.decodeHTML("asdf &amp; &yuml; &uuml; &apos;"); // "asdf & ÿ ü '"
```
<!-- TODO extend API -->
---
License: BSD-2-Clause
--check-leaks
--reporter spec
var assert = require("assert"),
path = require("path"),
entities = require("../");
describe("Encode->decode test", function() {
var testcases = [
{
input: "asdf & ÿ ü '",
xml: "asdf &amp; &#xFF; &#xFC; &apos;",
html: "asdf &amp; &yuml; &uuml; &apos;"
},
{
input: "&#38;",
xml: "&amp;#38;",
html: "&amp;&num;38&semi;"
}
];
testcases.forEach(function(tc) {
var encodedXML = entities.encodeXML(tc.input);
it("should XML encode " + tc.input, function() {
assert.equal(encodedXML, tc.xml);
});
it("should default to XML encode " + tc.input, function() {
assert.equal(entities.encode(tc.input), tc.xml);
});
it("should XML decode " + encodedXML, function() {
assert.equal(entities.decodeXML(encodedXML), tc.input);
});
it("should default to XML encode " + encodedXML, function() {
assert.equal(entities.decode(encodedXML), tc.input);
});
it("should default strict to XML encode " + encodedXML, function() {
assert.equal(entities.decodeStrict(encodedXML), tc.input);
});
var encodedHTML5 = entities.encodeHTML5(tc.input);
it("should HTML5 encode " + tc.input, function() {
assert.equal(encodedHTML5, tc.html);
});
it("should HTML5 decode " + encodedHTML5, function() {
assert.equal(entities.decodeHTML(encodedHTML5), tc.input);
});
});
it("should encode data URIs (issue 16)", function() {
var data = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAALAAABAAEAAAIBRAA7";
assert.equal(entities.decode(entities.encode(data)), data);
});
});
describe("Decode test", function() {
var testcases = [
{ input: "&amp;amp;", output: "&amp;" },
{ input: "&amp;#38;", output: "&#38;" },
{ input: "&amp;#x26;", output: "&#x26;" },
{ input: "&amp;#X26;", output: "&#X26;" },
{ input: "&#38;#38;", output: "&#38;" },
{ input: "&#x26;#38;", output: "&#38;" },
{ input: "&#X26;#38;", output: "&#38;" },
{ input: "&#x3a;", output: ":" },
{ input: "&#x3A;", output: ":" },
{ input: "&#X3a;", output: ":" },
{ input: "&#X3A;", output: ":" }
];
testcases.forEach(function(tc) {
it("should XML decode " + tc.input, function() {
assert.equal(entities.decodeXML(tc.input), tc.output);
});
it("should HTML4 decode " + tc.input, function() {
assert.equal(entities.decodeHTML(tc.input), tc.output);
});
it("should HTML5 decode " + tc.input, function() {
assert.equal(entities.decodeHTML(tc.input), tc.output);
});
});
});
var levels = ["xml", "entities"];
describe("Documents", function() {
levels
.map(function(n) {
return path.join("..", "maps", n);
})
.map(require)
.forEach(function(doc, i) {
describe("Decode", function() {
it(levels[i], function() {
Object.keys(doc).forEach(function(e) {
for (var l = i; l < levels.length; l++) {
assert.equal(entities.decode("&" + e + ";", l), doc[e]);
}
});
});
});
describe("Decode strict", function() {
it(levels[i], function() {
Object.keys(doc).forEach(function(e) {
for (var l = i; l < levels.length; l++) {
assert.equal(entities.decodeStrict("&" + e + ";", l), doc[e]);
}
});
});
});
describe("Encode", function() {
it(levels[i], function() {
Object.keys(doc).forEach(function(e) {
for (var l = i; l < levels.length; l++) {
assert.equal(entities.decode(entities.encode(doc[e], l), l), doc[e]);
}
});
});
});
});
var legacy = require("../maps/legacy.json");
describe("Legacy", function() {
it("should decode", runLegacy);
});
function runLegacy() {
Object.keys(legacy).forEach(function(e) {
assert.equal(entities.decodeHTML("&" + e), legacy[e]);
});
}
});
var astral = {
"1D306": "\uD834\uDF06",
"1D11E": "\uD834\uDD1E"
};
var astralSpecial = {
"80": "\u20AC",
"110000": "\uFFFD"
};
describe("Astral entities", function() {
Object.keys(astral).forEach(function(c) {
it("should decode " + astral[c], function() {
assert.equal(entities.decode("&#x" + c + ";"), astral[c]);
});
it("should encode " + astral[c], function() {
assert.equal(entities.encode(astral[c]), "&#x" + c + ";");
});
it("should escape " + astral[c], function() {
assert.equal(entities.escape(astral[c]), "&#x" + c + ";");
});
});
Object.keys(astralSpecial).forEach(function(c) {
it("special should decode \\u" + c, function() {
assert.equal(entities.decode("&#x" + c + ";"), astralSpecial[c]);
});
});
});
describe("Escape", function() {
it("should always decode ASCII chars", function() {
for (var i = 0; i < 0x7f; i++) {
var c = String.fromCharCode(i);
assert.equal(entities.decodeXML(entities.escape(c)), c);
}
});
});
dist: trusty
language: node_js
node_js:
- "8"
before_script:
- npm install -g mocha
script: npm test
addons:
apt:
packages:
- libnss3
MIT License
Copyright (c) 2016 Bobby Brennan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# rss-parser
[![Version][npm-image]][npm-link]
[![Build Status][build-image]][build-link]
[![Downloads][downloads-image]][npm-link]
[downloads-image]: https://img.shields.io/npm/dm/rss-parser.svg
[npm-image]: https://img.shields.io/npm/v/rss-parser.svg
[npm-link]: https://npmjs.org/package/rss-parser
[build-image]: https://travis-ci.org/bobby-brennan/rss-parser.svg?branch=master
[build-link]: https://travis-ci.org/bobby-brennan/rss-parser
A small library for turning RSS XML feeds into JavaScript objects.
## Installation
```bash
npm install --save rss-parser
```
## Usage
You can parse RSS from a URL (`parser.parseURL`) or an XML string (`parser.parseString`).
Both callbacks and Promises are supported.
### NodeJS
Here's an example in NodeJS using Promises with async/await:
```js
let Parser = require('rss-parser');
let parser = new Parser();
(async () => {
let feed = await parser.parseURL('https://www.reddit.com/.rss');
console.log(feed.title);
feed.items.forEach(item => {
console.log(item.title + ':' + item.link)
});
})();
```
### Web
> We recommend using a bundler like [webpack](https://webpack.js.org/), but we also provide
> pre-built browser distributions in the `dist/` folder. If you use the pre-built distribution,
> you'll need a [polyfill](https://github.com/taylorhakes/promise-polyfill) for Promise support.
Here's an example in the browser using callbacks:
```html
<script src="/node_modules/rss-parser/dist/rss-parser.min.js"></script>
<script>
// Note: some RSS feeds can't be loaded in the browser due to CORS security.
// To get around this, you can use a proxy.
const CORS_PROXY = "https://cors-anywhere.herokuapp.com/"
let parser = new RSSParser();
parser.parseURL(CORS_PROXY + 'https://www.reddit.com/.rss', function(err, feed) {
console.log(feed.title);
feed.items.forEach(function(entry) {
console.log(entry.title + ':' + entry.link);
})
})
</script>
```
### Upgrading from v2 to v3
A few minor breaking changes were made in v3. Here's what you need to know:
* You need to construct a `new Parser()` before calling `parseString` or `parseURL`
* `parseFile` is no longer available (for better browser support)
* `options` are now passed to the Parser constructor
* `parsed.feed` is now just `feed` (top-level object removed)
* `feed.entries` is now `feed.items` (to better match RSS XML)
## Output
Check out the full output format in [test/output/reddit.json](test/output/reddit.json)
```yaml
feedUrl: 'https://www.reddit.com/.rss'
title: 'reddit: the front page of the internet'
description: ""
link: 'https://www.reddit.com/'
items:
- title: 'The water is too deep, so he improvises'
link: 'https://www.reddit.com/r/funny/comments/3skxqc/the_water_is_too_deep_so_he_improvises/'
pubDate: 'Thu, 12 Nov 2015 21:16:39 +0000'
creator: "John Doe"
content: '<a href="http://example.com">this is a link</a> &amp; <b>this is bold text</b>'
contentSnippet: 'this is a link & this is bold text'
guid: 'https://www.reddit.com/r/funny/comments/3skxqc/the_water_is_too_deep_so_he_improvises/'
categories:
- funny
isoDate: '2015-11-12T21:16:39.000Z'
```
##### Notes:
* The `contentSnippet` field strips out HTML tags and unescapes HTML entities
* The `dc:` prefix will be removed from all fields
* Both `dc:date` and `pubDate` will be available in ISO 8601 format as `isoDate`
* If `author` is specified, but not `dc:creator`, `creator` will be set to `author` ([see article](http://www.lowter.com/blogs/2008/2/9/rss-dccreator-author))
* Atom's `updated` becomes `lastBuildDate` for consistency
## Options
### Custom Fields
If your RSS feed contains fields that aren't currently returned, you can access them using the `customFields` option.
```js
let parser = new Parser({
customFields: {
feed: ['otherTitle', 'extendedDescription'],
item: ['coAuthor','subtitle'],
}
});
parser.parseURL('https://www.reddit.com/.rss', function(err, feed) {
console.log(feed.extendedDescription);
feed.items.forEach(function(entry) {
console.log(entry.coAuthor + ':' + entry.subtitle);
})
})
```
To rename fields, you can pass in an array with two items, in the format `[fromField, toField]`:
```js
let parser = new Parser({
customFields: {
item: [
['dc:coAuthor', 'coAuthor'],
]
}
})
```
To pass additional flags, provide an object as the third array item. Currently there is one such flag:
* `keepArray`: `true` to return *all* values for fields that can have multiple entries. Default: return the first item only.
```js
let parser = new Parser({
customFields: {
item: [
['media:content', 'media:content', {keepArray: true}],
]
}
})
```
### Default RSS version
If your RSS Feed doesn't contain a `<rss>` tag with a `version` attribute,
you can pass a `defaultRSS` option for the Parser to use:
```js
let parser = new Parser({
defaultRSS: 2.0
});
```
### xml2js passthrough
`rss-parser` uses [xml2js](https://github.com/Leonidas-from-XIV/node-xml2js)
to parse XML. You can pass [these options](https://github.com/Leonidas-from-XIV/node-xml2js#options)
to `new xml2js.Parser()` by specifying `options.xml2js`:
```js
let parser = new Parser({
xml2js: {
emptyTag: '--EMPTY--',
}
});
```
### Headers
You can pass headers to the HTTP request:
```js
let parser = new Parser({
headers: {'User-Agent': 'something different'},
});
```
### Redirects
By default, `parseURL` will follow up to five redirects. You can change this
with `options.maxRedirects`.
```js
let parser = new Parser({maxRedirects: 100});
```
## Contributing
Contributions are welcome! If you are adding a feature or fixing a bug, please be sure to add a [test case](https://github.com/bobby-brennan/rss-parser/tree/master/test/input)
### Running Tests
The tests run the RSS parser for several sample RSS feeds in `test/input` and outputs the resulting JSON into `test/output`. If there are any changes to the output files the tests will fail.
To check if your changes affect the output of any test cases, run
`npm test`
To update the output files with your changes, run
`WRITE_GOLDEN=true npm test`
### Publishing Releases
```bash
npm run build
git commit -a -m "Build distribution"
npm version minor # or major/patch
npm publish
git push --follow-tags
```
{
"name": "rss-parser",
"description": "",
"version": "1.1.0",
"main": "dist/rss-parser.js",
"authors": [
"Bobby Brennan"
],
"license": "MIT",
"homepage": "https://github.com/bobby-brennan/rss-parser",
"moduleType": [
"node"
],
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
window.RSSParser = require('./index');
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
import { Options } from 'xml2js';
interface Headers
{
readonly Accept: string;
readonly 'User-Agent': string;
}
interface CustomFields
{
readonly feed?: string[];
readonly item?: string[] | string[][];
}
interface ParserOptions
{
readonly xml2js?: Options;
readonly headers?: Headers;
readonly defaultRSS?: number;
readonly maxRedirects?: number;
readonly customFields?: CustomFields;
}
interface Items
{
readonly link: string;
readonly guid: string;
readonly title: string;
readonly pubDate: string;
readonly creator: string;
readonly content: string;
readonly isoDate: string;
readonly categories: string[];
readonly contentSnippet: string;
}
interface Output
{
readonly link: string;
readonly title: string;
readonly items: Items[];
readonly feedUrl: string;
readonly description: string;
readonly itunes: {
image: string;
owner: {
name: string;
email: string;
};
author: string;
summary: string;
explicit: string;
};
}
/**
* Class that handles all parsing or URL, or even XML, RSS feed to JSON.
*/
declare const Parser: {
/**
* @param options - Parser options.
*/
new(options?: ParserOptions): {
/**
* Parse XML content to JSON.
*
* @param xml - The xml to be parsed.
* @param callback - Traditional callback.
*
* @returns Promise that has the same Output as the callback.
*/
parseString(xml: string, callback?: (err: Error, feed: Output) => void): Promise<Output>;
/**
* Parse URL content to JSON.
*
* @param feedUrl - The url that needs to be parsed to JSON.
* @param callback - Traditional callback.
* @param redirectCount - Max of redirects, default is set to five.
*
* @example
* await parseURL('https://www.reddit.com/.rss');
* parseURL('https://www.reddit.com/.rss', (err, feed) => { ... });
*
* @returns Promise that has the same Output as the callback.
*/
parseURL(feedUrl: string, callback?: (err: Error, feed: Output) => void, redirectCount?: number): Promise<Output>;
};
}
export = Parser
'use strict';
module.exports = require('./lib/parser');
const fields = module.exports = {};
fields.feed = [
['author', 'creator'],
['dc:publisher', 'publisher'],
['dc:creator', 'creator'],
['dc:source', 'source'],
['dc:title', 'title'],
['dc:type', 'type'],
'title',
'description',
'author',
'pubDate',
'webMaster',
'managingEditor',
'generator',
'link',
'language',
'copyright',
'lastBuildDate',
'docs',
'generator',
'ttl',
'rating',
'skipHours',
'skipDays',
];
fields.item = [
['author', 'creator'],
['dc:creator', 'creator'],
['dc:date', 'date'],
['dc:language', 'language'],
['dc:rights', 'rights'],
['dc:source', 'source'],
['dc:title', 'title'],
'title',
'link',
'pubDate',
'author',
'content:encoded',
'enclosure',
'dc:creator',
'dc:date',
'comments',
];
var mapItunesField = function(f) {
return ['itunes:' + f, f];
}
fields.podcastFeed = ([
'author',
'subtitle',
'summary',
'explicit'
]).map(mapItunesField);
fields.podcastItem = ([
'author',
'subtitle',
'summary',
'explicit',
'duration',
'image',
'episode',
'image',
'season',
'keywords',
]).map(mapItunesField);
"use strict";
const http = require('http');
const https = require('https');
const xml2js = require('xml2js');
const url = require('url');
const fields = require('./fields');
const utils = require('./utils');
const DEFAULT_HEADERS = {
'User-Agent': 'rss-parser',
'Accept': 'application/rss+xml',
}
const DEFAULT_MAX_REDIRECTS = 5;
class Parser {
constructor(options={}) {
options.headers = options.headers || {};
options.xml2js = options.xml2js || {};
options.customFields = options.customFields || {};
options.customFields.item = options.customFields.item || [];
options.customFields.feed = options.customFields.feed || [];
if (!options.maxRedirects) options.maxRedirects = DEFAULT_MAX_REDIRECTS;
this.options = options;
this.xmlParser = new xml2js.Parser(this.options.xml2js);
}
parseString(xml, callback) {
let prom = new Promise((resolve, reject) => {
this.xmlParser.parseString(xml, (err, result) => {
if (err) return reject(err);
if (!result) {
return reject(new Error('Unable to parse XML.'));
}
let feed = null;
if (result.feed) {
feed = this.buildAtomFeed(result);
} else if (result.rss && result.rss.$ && result.rss.$.version && result.rss.$.version.match(/^2/)) {
feed = this.buildRSS2(result);
} else if (result['rdf:RDF']) {
feed = this.buildRSS1(result);
} else if (result.rss && result.rss.$ && result.rss.$.version && result.rss.$.version.match(/0\.9/)) {
feed = this.buildRSS0_9(result);
} else if (result.rss && this.options.defaultRSS) {
switch(this.options.defaultRSS) {
case 0.9:
feed = this.buildRSS0_9(result);
break;
case 1:
feed = this.buildRSS1(result);
break;
case 2:
feed = this.buildRSS2(result);
break;
default:
return reject(new Error("default RSS version not recognized."))
}
} else {
return reject(new Error("Feed not recognized as RSS 1 or 2."))
}
resolve(feed);
});
});
prom = utils.maybePromisify(callback, prom);
return prom;
}
parseURL(feedUrl, callback, redirectCount=0) {
let xml = '';
let get = feedUrl.indexOf('https') === 0 ? https.get : http.get;
let urlParts = url.parse(feedUrl);
let headers = Object.assign({}, DEFAULT_HEADERS, this.options.headers);
let prom = new Promise((resolve, reject) => {
let req = get({
headers,
auth: urlParts.auth,
protocol: urlParts.protocol,
hostname: urlParts.hostname,
port: urlParts.port,
path: urlParts.path,
}, (res) => {
if (this.options.maxRedirects && res.statusCode >= 300 && res.statusCode < 400 && res.headers['location']) {
if (redirectCount === this.options.maxRedirects) {
return reject(new Error("Too many redirects"));
} else {
return this.parseURL(res.headers['location'], null, redirectCount + 1).then(resolve, reject);
}
} else if (res.statusCode >= 300) {
return reject(new Error("Status code " + res.statusCode))
}
let encoding = utils.getEncodingFromContentType(res.headers['content-type']);
res.setEncoding(encoding);
res.on('data', (chunk) => {
xml += chunk;
});
res.on('end', () => {
return this.parseString(xml).then(resolve, reject);
});
})
req.on('error', reject);
});
prom = utils.maybePromisify(callback, prom);
return prom;
}
buildAtomFeed(xmlObj) {
let feed = {items: []};
utils.copyFromXML(xmlObj.feed, feed, this.options.customFields.feed);
if (xmlObj.feed.link) {
feed.link = utils.getLink(xmlObj.feed.link, 'alternate', 0);
feed.feedUrl = utils.getLink(xmlObj.feed.link, 'self', 1);
}
if (xmlObj.feed.title) {
let title = xmlObj.feed.title[0] || '';
if (title._) title = title._
if (title) feed.title = title;
}
if (xmlObj.feed.updated) {
feed.lastBuildDate = xmlObj.feed.updated[0];
}
(xmlObj.feed.entry || []).forEach(entry => {
let item = {};
utils.copyFromXML(entry, item, this.options.customFields.item);
if (entry.title) {
let title = entry.title[0] || '';
if (title._) title = title._;
if (title) item.title = title;
}
if (entry.link && entry.link.length) {
item.link = utils.getLink(entry.link, 'alternate', 0);
}
if (entry.published && entry.published.length && entry.published[0].length) item.pubDate = new Date(entry.published[0]).toISOString();
if (!item.pubDate && entry.updated && entry.updated.length && entry.updated[0].length) item.pubDate = new Date(entry.updated[0]).toISOString();
if (entry.author && entry.author.length) item.author = entry.author[0].name[0];
if (entry.content && entry.content.length) {
item.content = utils.getContent(entry.content[0]);
item.contentSnippet = utils.getSnippet(item.content)
}
if (entry.id) {
item.id = entry.id[0];
}
this.setISODate(item);
feed.items.push(item);
});
return feed;
}
buildRSS0_9(xmlObj) {
var channel = xmlObj.rss.channel[0];
var items = channel.item;
return this.buildRSS(channel, items);
}
buildRSS1(xmlObj) {
xmlObj = xmlObj['rdf:RDF'];
let channel = xmlObj.channel[0];
let items = xmlObj.item;
return this.buildRSS(channel, items);
}
buildRSS2(xmlObj) {
let channel = xmlObj.rss.channel[0];
let items = channel.item;
let feed = this.buildRSS(channel, items);
if (xmlObj.rss.$ && xmlObj.rss.$['xmlns:itunes']) {
this.decorateItunes(feed, channel);
}
return feed;
}
buildRSS(channel, items) {
items = items || [];
let feed = {items: []};
let feedFields = fields.feed.concat(this.options.customFields.feed);
let itemFields = fields.item.concat(this.options.customFields.item);
if (channel['atom:link']) feed.feedUrl = channel['atom:link'][0].$.href;
if (channel.image && channel.image[0] && channel.image[0].url) {
feed.image = {};
let image = channel.image[0];
if (image.link) feed.image.link = image.link[0];
if (image.url) feed.image.url = image.url[0];
if (image.title) feed.image.title = image.title[0];
if (image.width) feed.image.width = image.width[0];
if (image.height) feed.image.height = image.height[0];
}
utils.copyFromXML(channel, feed, feedFields);
items.forEach(xmlItem => {
let item = {};
utils.copyFromXML(xmlItem, item, itemFields);
if (xmlItem.enclosure) {
item.enclosure = xmlItem.enclosure[0].$;
}
if (xmlItem.description) {
item.content = utils.getContent(xmlItem.description[0]);
item.contentSnippet = utils.getSnippet(item.content);
}
if (xmlItem.guid) {
item.guid = xmlItem.guid[0];
if (item.guid._) item.guid = item.guid._;
}
if (xmlItem.category) item.categories = xmlItem.category;
this.setISODate(item);
feed.items.push(item);
});
return feed;
}
/**
* Add iTunes specific fields from XML to extracted JSON
*
* @access public
* @param {object} feed extracted
* @param {object} channel parsed XML
*/
decorateItunes(feed, channel) {
let items = channel.item || [],
entry = {};
feed.itunes = {}
if (channel['itunes:owner']) {
let owner = {},
image;
if(channel['itunes:owner'][0]['itunes:name']) {
owner.name = channel['itunes:owner'][0]['itunes:name'][0];
}
if(channel['itunes:owner'][0]['itunes:email']) {
owner.email = channel['itunes:owner'][0]['itunes:email'][0];
}
if(channel['itunes:image']) {
let hasImageHref = (channel['itunes:image'][0] &&
channel['itunes:image'][0].$ &&
channel['itunes:image'][0].$.href);
image = hasImageHref ? channel['itunes:image'][0].$.href : null;
}
if(image) {
feed.itunes.image = image;
}
feed.itunes.owner = owner;
}
utils.copyFromXML(channel, feed.itunes, fields.podcastFeed);
items.forEach((item, index) => {
let entry = feed.items[index];
entry.itunes = {};
utils.copyFromXML(item, entry.itunes, fields.podcastItem);
let image = item['itunes:image'];
if (image && image[0] && image[0].$ && image[0].$.href) {
entry.itunes.image = image[0].$.href;
}
});
}
setISODate(item) {
let date = item.pubDate || item.date;
if (date) {
try {
item.isoDate = new Date(date.trim()).toISOString();
} catch (e) {
// Ignore bad date format
}
}
}
}
module.exports = Parser;
const utils = module.exports = {};
const entities = require('entities');
const xml2js = require('xml2js');
utils.stripHtml = function(str) {
return str.replace(/<(?:.|\n)*?>/gm, '');
}
utils.getSnippet = function(str) {
return entities.decode(utils.stripHtml(str)).trim();
}
utils.getLink = function(links, rel, fallbackIdx) {
if (!links) return;
for (let i = 0; i < links.length; ++i) {
if (links[i].$.rel === rel) return links[i].$.href;
}
if (links[fallbackIdx]) return links[fallbackIdx].$.href;
}
utils.getContent = function(content) {
if (typeof content._ === 'string') {
return content._;
} else if (typeof content === 'object') {
let builder = new xml2js.Builder({headless: true, explicitRoot: true, rootName: 'div', renderOpts: {pretty: false}});
return builder.buildObject(content);
} else {
return content;
}
}
utils.copyFromXML = function(xml, dest, fields) {
fields.forEach(function(f) {
let from = f;
let to = f;
let options = {};
if (Array.isArray(f)) {
from = f[0];
to = f[1];
if (f.length > 2) {
options = f[2];
}
}
const { keepArray } = options;
if (xml[from] !== undefined)
dest[to] = keepArray ? xml[from] : xml[from][0];
})
}
utils.maybePromisify = function(callback, promise) {
if (!callback) return promise;
return promise.then(
data => setTimeout(() => callback(null, data)),
err => setTimeout(() => callback(err))
);
}
const DEFAULT_ENCODING = 'utf8';
const ENCODING_REGEX = /(encoding|charset)\s*=\s*(\S+)/;
const SUPPORTED_ENCODINGS = ['ascii', 'utf8', 'utf16le', 'ucs2', 'base64', 'latin1', 'binary', 'hex'];
const ENCODING_ALIASES = {
'utf-8': 'utf8',
'iso-8859-1': 'latin1',
}
utils.getEncodingFromContentType = function(contentType) {
contentType = contentType || '';
let match = contentType.match(ENCODING_REGEX);
let encoding = (match || [])[2] || '';
encoding = encoding.toLowerCase();
encoding = ENCODING_ALIASES[encoding] || encoding;
if (!encoding || SUPPORTED_ENCODINGS.indexOf(encoding) === -1) {
encoding = DEFAULT_ENCODING;
}
return encoding;
}
{
"_from": "rss-parser",
"_id": "rss-parser@3.5.4",
"_inBundle": false,
"_integrity": "sha512-dC7wHtz/p8QWQnsGgCB+HEYE01Dk8/AHMzSk0ZvoV3S0mhBqQNO/yi3H2fPh3qV2NNLNNEBg+8ZDSipKxjR5tQ==",
"_location": "/rss-parser",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "rss-parser",
"name": "rss-parser",
"escapedName": "rss-parser",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.5.4.tgz",
"_shasum": "3b267d96c57bdc22ff5cc847ef9bcd3dce4ae2cc",
"_spec": "rss-parser",
"_where": "C:\\Users\\정민채\\Desktop\\TermProject\\2017104024정민혁KakaoBot",
"author": {
"name": "Bobby Brennan"
},
"bugs": {
"url": "https://github.com/bobby-brennan/rss-parser/issues"
},
"bundleDependencies": false,
"dependencies": {
"entities": "^1.1.1",
"xml2js": "^0.4.19"
},
"deprecated": false,
"description": "A lightweight RSS parser, for Node and the browser",
"devDependencies": {
"@types/xml2js": "^0.4.3",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"chai": "^3.4.1",
"express": "^4.16.3",
"mocha": "^5.2.0",
"puppeteer": "^1.8.0",
"webpack": "^3.12.0"
},
"directories": {
"test": "test"
},
"homepage": "https://github.com/bobby-brennan/rss-parser#readme",
"keywords": [
"RSS",
"RSS to JSON",
"RSS reader",
"RSS parser",
"RSS to JS",
"Feed reader"
],
"license": "MIT",
"main": "index.js",
"name": "rss-parser",
"repository": {
"type": "git",
"url": "git+https://github.com/bobby-brennan/rss-parser.git"
},
"scripts": {
"build": "./scripts/build.sh",
"test": "mocha --exit"
},
"types": "index.d.ts",
"version": "3.5.4"
}
set -e
webpack
cp dist/rss-parser.min.js dist/rss-parser.js
webpack -p
"use strict";
const express = require('express');
const expect = require('chai').expect;
const Browser = require('puppeteer');
let browser = null;
let page = null;
const PORT = 3333;
const PARSE_TIMEOUT = 1000;
describe('Browser', function() {
if (process.env.SKIP_BROWSER_TESTS) {
console.log('skipping browser tests');
return;
}
before(function(done) {
this.timeout(5000);
let app = express();
app.use(express.static(__dirname));
app.use('/dist', express.static(__dirname + '/../dist'));
app.listen(PORT, err => {
if (err) return done(err);
Browser.launch({args: ['--no-sandbox']})
.then(b => browser = b)
.then(_ => browser.newPage())
.then(p => {
page = p;
return page.goto('http://localhost:3333/index.html');
})
.then(_ => done())
.catch(e => done(e));
});
});
after(() => browser.close());
it('should have window.RSSParser', () => {
return page.evaluate(() => {
return typeof window.RSSParser;
}).then(type => {
expect(type).to.equal('function');
})
});
it('should parse reddit', function() {
this.timeout(PARSE_TIMEOUT + 1000);
return page.evaluate(() => {
var parser = new RSSParser();
parser.parseURL('http://localhost:3333/input/reddit.rss', function(err, data) {
window.error = err;
window.reddit = data;
})
})
.then(_ => {
return new Promise(resolve => setTimeout(resolve, PARSE_TIMEOUT))
})
.then(_ => page.evaluate(() => {
return window.error;
}))
.then(err => {
expect(err).to.equal(null);
})
.then(_ => page.evaluate(() => {
return window.reddit.title;
}))
.then(title => {
expect(title).to.equal('reddit: the front page of the internet');
})
})
})
<script src="dist/rss-parser.min.js"></script>
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xml:lang="en-US">
<id>tag:github.com,2008:https://github.com/gulpjs/gulp/releases</id>
<link type="text/html" rel="alternate" href="https://github.com/gulpjs/gulp/releases"/>
<link type="application/atom+xml" rel="self" href="https://github.com/gulpjs/gulp/releases.atom"/>
<title>Release notes from gulp</title>
<updated>2015-06-01T23:49:41+02:00</updated>
<entry>
<id>tag:github.com,2008:Repository/11167738/v3.9.0</id>
<updated>2015-06-01T23:49:41+02:00</updated>
<link rel="alternate" type="text/html" href="/gulpjs/gulp/releases/tag/v3.9.0"/>
<title>v3.9.0</title>
<content type="html">&lt;p&gt;3.9.0&lt;/p&gt;</content>
<author>
<name>contra</name>
</author>
<media:thumbnail height="30" width="30" url="https://avatars3.githubusercontent.com/u/425716?v=3&amp;s=60"/>
</entry>
<entry>
<id>tag:github.com,2008:Repository/11167738/v3.8.11</id>
<updated>2015-02-09T21:37:28+01:00</updated>
<link rel="alternate" type="text/html" href="/gulpjs/gulp/releases/tag/v3.8.11"/>
<title>v3.8.11</title>
<content type="html">&lt;p&gt;3.8.11&lt;/p&gt;</content>
<author>
<name>contra</name>
</author>
<media:thumbnail height="30" width="30" url="https://avatars3.githubusercontent.com/u/425716?v=3&amp;s=60"/>
</entry>
<entry>
<id>tag:github.com,2008:Repository/11167738/v3.8.10</id>
<updated>2014-11-04T01:11:30+01:00</updated>
<link rel="alternate" type="text/html" href="/gulpjs/gulp/releases/tag/v3.8.10"/>
<title>v3.8.10</title>
<content type="html">&lt;p&gt;3.8.10&lt;/p&gt;</content>
<author>
<name>contra</name>
</author>
<media:thumbnail height="30" width="30" url="https://avatars3.githubusercontent.com/u/425716?v=3&amp;s=60"/>
</entry>
<entry>
<id>tag:github.com,2008:Repository/11167738/v3.8.9</id>
<updated>2014-10-22T08:55:20+02:00</updated>
<link rel="alternate" type="text/html" href="/gulpjs/gulp/releases/tag/v3.8.9"/>
<title>v3.8.9</title>
<content type="html">&lt;p&gt;3.8.9&lt;/p&gt;</content>
<author>
<name>contra</name>
</author>
<media:thumbnail height="30" width="30" url="https://avatars3.githubusercontent.com/u/425716?v=3&amp;s=60"/>
</entry>
<entry>
<id>tag:github.com,2008:Repository/11167738/v3.8.8</id>
<updated>2014-09-07T22:20:11+02:00</updated>
<link rel="alternate" type="text/html" href="/gulpjs/gulp/releases/tag/v3.8.8"/>
<title>v3.8.8</title>
<content type="html">&lt;p&gt;3.8.8&lt;/p&gt;</content>
<author>
<name>contra</name>
</author>
<media:thumbnail height="30" width="30" url="https://avatars3.githubusercontent.com/u/425716?v=3&amp;s=60"/>
</entry>
<entry>
<id>tag:github.com,2008:Repository/11167738/v3.8.7</id>
<updated>2014-08-02T06:58:19+02:00</updated>
<link rel="alternate" type="text/html" href="/gulpjs/gulp/releases/tag/v3.8.7"/>
<title>v3.8.7</title>
<content type="html">&lt;p&gt;3.8.7&lt;/p&gt;</content>
<author>
<name>contra</name>
</author>
<media:thumbnail height="30" width="30" url="https://avatars3.githubusercontent.com/u/425716?v=3&amp;s=60"/>
</entry>
<entry>
<id>tag:github.com,2008:Repository/11167738/v3.8.6</id>
<updated>2014-07-10T00:06:50+02:00</updated>
<link rel="alternate" type="text/html" href="/gulpjs/gulp/releases/tag/v3.8.6"/>
<title>v3.8.6</title>
<content type="html">&lt;p&gt;3.8.6&lt;/p&gt;</content>
<author>
<name>contra</name>
</author>
<media:thumbnail height="30" width="30" url="https://avatars3.githubusercontent.com/u/425716?v=3&amp;s=60"/>
</entry>
<entry>
<id>tag:github.com,2008:Repository/11167738/v3.8.5</id>
<updated>2014-06-27T08:53:54+02:00</updated>
<link rel="alternate" type="text/html" href="/gulpjs/gulp/releases/tag/v3.8.5"/>
<title>v3.8.5</title>
<content type="html">&lt;p&gt;3.8.5&lt;/p&gt;</content>
<author>
<name>contra</name>
</author>
<media:thumbnail height="30" width="30" url="https://avatars3.githubusercontent.com/u/425716?v=3&amp;s=60"/>
</entry>
<entry>
<id>tag:github.com,2008:Repository/11167738/v3.8.4</id>
<updated>2014-06-27T08:38:43+02:00</updated>
<link rel="alternate" type="text/html" href="/gulpjs/gulp/releases/tag/v3.8.4"/>
<title>v3.8.4</title>
<content type="html">&lt;p&gt;3.8.4&lt;/p&gt;</content>
<author>
<name>contra</name>
</author>
<media:thumbnail height="30" width="30" url="https://avatars3.githubusercontent.com/u/425716?v=3&amp;s=60"/>
</entry>
<entry>
<id>tag:github.com,2008:Repository/11167738/v3.8.3</id>
<updated>2014-06-26T23:17:51+02:00</updated>
<link rel="alternate" type="text/html" href="/gulpjs/gulp/releases/tag/v3.8.3"/>
<title>v3.8.3</title>
<content type="html">&lt;p&gt;3.8.3&lt;/p&gt;</content>
<author>
<name>contra</name>
</author>
<media:thumbnail height="30" width="30" url="https://avatars3.githubusercontent.com/u/425716?v=3&amp;s=60"/>
</entry>
</feed>
This diff is collapsed. Click to expand it.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<rss version="0.92">
<channel>
<title>RSS0.92 Example</title>
<link>http://www.oreilly.com/example/index.html</link>
<description>This is an example RSS0.91 feed</description>
<language>en-gb</language>
<copyright>Copyright 2002, Oreilly and Associates.</copyright>
<managingEditor>editor@oreilly.com</managingEditor>
<webMaster>webmaster@oreilly.com</webMaster>
<rating>5</rating>
<pubDate>03 Apr 02 1500 GMT</pubDate>
<lastBuildDate>03 Apr 02 1500 GMT</lastBuildDate>
<item>
<title>The First Item</title>
<link>http://www.oreilly.com/example/001.html</link>
<description>This is the first item.</description>
<source url="http://www.anothersite.com/index.xml">Another Site</source>
<enclosure url="http://www.oreilly.com/001.mp3" length="54321" type="audio/mpeg"/>
<category domain="http://www.dmoz.org">Business/Industries/Publishing/Publishers/Nonfiction/</category>
</item>
<item>
<title>The Second Item</title>
<link>http://www.oreilly.com/example/002.html</link>
<description>This is the second item.</description>
<source url="http://www.anothersite.com/index.xml">Another Site</source>
<enclosure url="http://www.oreilly.com/002.mp3" length="54321" type="audio/mpeg"/>
<category domain="http://www.dmoz.org">Business/Industries/Publishing/Publishers/Nonfiction/</category>
</item>
</channel>
</rss>
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
<channel>
<title>Instant Article Test</title>
<link>https://localhost:8000</link>
<description>1, 2, 1, 2… check the mic!</description>
<language>en</language>
<pubDate>Fri, 13 May 2016 15:14:05 GMT</pubDate>
<dc:date>2016-05-13T15:14:05Z</dc:date>
<dc:language>en</dc:language>
<item>
<title>My first Instant Article</title>
<link>https://localhost:8000</link>
<description>Lorem ipsum</description>
<content:encoded>&lt;b&gt;Lorem&lt;/b&gt; ipsum</content:encoded>
<pubDate>Wed, 04 May 2016 06:53:45 GMT</pubDate>
<guid>https://localhost:8000</guid>
<dc:creator>tobi</dc:creator>
<dc:date>2016-05-04T06:53:45Z</dc:date>
</item>
</channel>
</rss>
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xml:lang="en-US">
<entry>
<id>tag:github.com,2008:Repository/11167738/v3.9.0</id>
</entry>
</feed>
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
<channel>
<title>foobar on Narro</title>
<link>http://on.narro.co/f</link>
<description>foobar uses Narro to create a podcast of articles transcribed to audio.</description>
<language>en</language>
<copyright>All article content copyright of respective source authors.</copyright>
<managingEditor>foobar@gmail.com</managingEditor>
<webMaster>josh@narro.co</webMaster>
<pubDate>Fri, 08 Jul 2016 13:40:00 UTC</pubDate>
<generator>gopod - http://github.com/jbckmn/gopod</generator>
<ttl>20</ttl>
<itunes:author>foobar@gmail.com</itunes:author>
<itunes:subtitle>foobar uses Narro to create a podcast of articles transcribed to audio.</itunes:subtitle>
<itunes:summary>foobar uses Narro to create a podcast of articles transcribed to audio.</itunes:summary>
<itunes:explicit>no</itunes:explicit>
<itunes:owner>
<itunes:name>foobar</itunes:name>
<itunes:email>foobar@gmail.com</itunes:email>
</itunes:owner>
<itunes:image href="https://www.narro.co/images/narro-icon-lg.png"></itunes:image>
<atom:link href="http://on.narro.co/f" rel="self" type="application/rss+xml"></atom:link>
<item>
<link>https://www.narro.co/article/54e703933058540300000069</link>
<description>Listen to your reading list anywhere. Narro will take your bookmarked articles and read them back to you as a podcast.&lt;br/&gt; http://www.narro.co/faq&lt;br/&gt; &lt;ul class=&#34;linkList&#34;&gt;&lt;/ul&gt;</description>
<title>FAQ for Narro</title>
<pubDate>Fri, 20 Feb 2015 09:51:15 UTC</pubDate>
<author>foobar@gmail.com</author>
<guid>https://www.narro.co/article/54e703933058540300000069</guid>
<itunes:author>foobar@gmail.com</itunes:author>
<itunes:subtitle>FAQ for Narro</itunes:subtitle>
<itunes:summary>Listen to your reading list anywhere. Narro will take your bookmarked articles and read them back to you as a podcast. ... http://www.narro.co/faq ... &lt;ul class=&#34;linkList&#34;&gt;&lt;/ul&gt;</itunes:summary>
<itunes:explicit>no</itunes:explicit>
<itunes:duration>74</itunes:duration>
<itunes:image href="http://example.com/someImage.jpg"/>
<enclosure url="https://s3.amazonaws.com/nareta-articles/audio/54d046c293f79c0300000003/7e2d2b00-a945-441a-f49b-063786a319a4.mp3" length="74" type="audio/mpeg"></enclosure>
</item>
</channel>
</rss>
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found <a HREF="http://fishhawk2.marketwatch.com/rss/pf/">here</a></body>
\ No newline at end of file
<rss>
<channel>
<title>UOL Noticias</title>
<link>http://noticias.uol.com.br/</link>
<description>Últimas Notícias</description>
<language></language>
<category>Notícias</category>
<copyright></copyright>
<image>
<title>UOL Noticias - Últimas Notícias</title>
<url>http://rss.i.uol.com.br/uol_rss.gif</url>
<link>http://noticias.uol.com.br/ultimas/</link>
</image>
<item>
<title><![CDATA[Ibope: Bolsonaro perde de Haddad, Ciro e Alckmin em simulações de 2º turno]]></title>
<link><![CDATA[https://noticias.uol.com.br/politica/eleicoes/2018/noticias/2018/09/24/ibope-bolsonaro-perde-de-haddad-ciro-e-alckmin-em-simulacoes-de-2-turno.htm]]></link>
<description><![CDATA[<img src='https://conteudo.imguol.com.br/c/noticias/5f/2018/09/17/presidenciaveis-1537211917356_142x100.jpg' align="left" /> Líder na pesquisa Ibope de intenção de voto para o primeiro turno divulgada nesta segunda-feira (24), o candidato do PSL a presidente, Jair Bolsonaro, não tem o mesmo desempenho nas simulações de segundo turno feitas pela empresa no mesmo levantamento. ]]></description>
<pubDate>Seg, 24 Set 2018 19:42:40 -0300</pubDate>
</item>
<item>
<title><![CDATA[Promotoria abre inquérito para apurar suspeita de improbidade de Skaf no Sebrae-SP]]></title>
<link><![CDATA[https://www1.folha.uol.com.br/poder/2018/09/promotoria-abre-inquerito-para-apurar-suspeita-de-improbidade-de-skaf-no-sebrae-sp.shtml]]></link>
<description></description>
<pubDate>Seg, 24 Set 2018 19:38:00 -0300</pubDate>
</item>
<item>
<title><![CDATA[Apucarana garante continuidade do Pré Aprendiz; ano vai fechar com 13 mil pessoas qualificadas]]></title>
<link><![CDATA[https://tnonline.uol.com.br/noticias/apucarana/45,470927,24,09,apucarana-garante-continuidade-do-pre-aprendiz-ano-vai-fechar-com-13-mil-pessoas-qualificadas]]></link>
<description><![CDATA[<img src='https://m1.tnonline.com.br/entre/2018/09/24/tn_4017f330b2_preapre.jpg' align="left" /> Programa Pré Aprendiz, que é realizado pela Secretaria Municipal de Assistência Social de Apucarana em parceria com o Serviço Social do Comércio (Sesc), terá continuidade em 2019. O termo de renovaç... ]]></description>
<pubDate>Seg, 24 Set 2018 19:35:07 -0300</pubDate>
</item>
<item>
<title><![CDATA[Dow Jones fecha em baixa de 0,68%]]></title>
<link><![CDATA[https://economia.uol.com.br/noticias/efe/2018/09/24/dow-jones-fecha-em-baixa-de-068.htm]]></link>
<description><![CDATA[ Nova York, 24 set (EFE).- O índice Dow Jones Industrial fechou nesta segunda-feira em baixa de 0,68% em mais um pregão marcado pela disputa comercial entre Estados Unidos e China e por especulações sobre a possível renúncia de Rod Rosenstein ao cargo de procurador-geral adjunto dos Estados Unidos. ]]></description>
<pubDate>Seg, 24 Set 2018 19:32:00 -0300</pubDate>
</item>
<item>
<title><![CDATA[Rival de Putin é condenado a mais 20 dias de prisão]]></title>
<link><![CDATA[https://noticias.uol.com.br/ultimas-noticias/ansa/2018/09/24/rival-de-putin-e-condenado-a-mais-20-dias-de-prisao.htm]]></link>
<description><![CDATA[ MOSCOU, 24 SET (ANSA) - O líder de oposição russo Alexei Navalny foi condenado na noite desta segunda-feira (24) a mais 20 dias de prisão por organizar manifestações não autorizadas contra o governo de Vladimir Putin, informou a mídia russa. Navalny foi preso nesta manhã pouco tempo depois de ser libertado da cadeia após cumprir outra sentença de 30 dias.    ]]></description>
<pubDate>Seg, 24 Set 2018 19:32:00 -0300</pubDate>
</item>
<item>
<title><![CDATA[Em entrevista, Bolsonaro chama proposta de Paulo Guedes para imposto de renda de "ousada"]]></title>
<link><![CDATA[https://noticias.uol.com.br/ultimas-noticias/reuters/2018/09/24/em-entrevista-bolsonaro-chama-proposta-de-paulo-guedes-para-imposto-de-renda-de-ousada.htm]]></link>
<description><![CDATA[ BRASÍLIA (Reuters) - O candidato do PSL à Presidência, Jair Bolsonaro, classificou nesta segunda-feira a proposta do seu principal assessor econômico, Paulo Guedes, para a mudança na forma de cobrança do imposto de renda para pessoa física de "ousada". ]]></description>
<pubDate>Seg, 24 Set 2018 19:30:42 -0300</pubDate>
</item>
<item>
<title><![CDATA[Relatório do governo dos EUA acusa militares de Mianmar de atrocidades contra muçulmanos rohingyas]]></title>
<link><![CDATA[https://noticias.uol.com.br/ultimas-noticias/reuters/2018/09/24/relatorio-do-governo-dos-eua-acusa-militares-de-mianmar-de-atrocidades-contra-muculmanos-rohingyas.htm]]></link>
<description><![CDATA[ Por Matt Spetalnick e Jason Szep ]]></description>
<pubDate>Seg, 24 Set 2018 19:29:18 -0300</pubDate>
</item>
<item>
<title><![CDATA[Enfermeira de Chávez alega 'perseguição' em Corte espanhola]]></title>
<link><![CDATA[https://noticias.uol.com.br/ultimas-noticias/ansa/2018/09/24/enfermeira-de-chavez-alega-perseguicao-em-corte-espanhola.htm]]></link>
<description><![CDATA[ MADRI, 24 SET (ANSA) - A ex-enfermeira do falecido Hugo Chávez, ex-presidente venezuelano, prestou depoimento hoje (24) na Corte Nacional da Espanha e alegou sofrer perseguiç... ]]></description>
<pubDate>Seg, 24 Set 2018 19:25:00 -0300</pubDate>
</item>
<item>
<title><![CDATA[Match Eleitoral já soma mais de 500 mil testes completos; ache seu candidato]]></title>
<link><![CDATA[https://www1.folha.uol.com.br/poder/2018/09/match-eleitoral-ja-soma-mais-de-500-mil-testes-completos-ache-seu-candidato.shtml]]></link>
<description></description>
<pubDate>Seg, 24 Set 2018 19:22:00 -0300</pubDate>
</item>
<item>
<title><![CDATA[Match Eleitoral já soma mais de 500 mil testes completos; ache seu candidato]]></title>
<link><![CDATA[https://redir.folha.com.br/redir/online/poder/eleicoes-2018/rss091/*https://www1.folha.uol.com.br/poder/2018/09/match-eleitoral-ja-soma-mais-de-500-mil-testes-completos-ache-seu-candidato.shtml]]></link>
<description><![CDATA[ Já são mais de 500 mil testes completos no Match Eleitoral, ferramenta criada pela Folha e pelo Datafolha para ajudar o eleitor a escolher seu deputado federal por São Paulo, Minas Gerais e Rio de Janeiro, além de senadores por São Paulo. Leia mais (09/24/2018 - 19h22) ]]></description>
<pubDate>Seg, 24 Set 2018 19:22:00 -0300</pubDate>
</item>
<item>
<title><![CDATA[Acordo adicional da Argentina com FMI está "perto de acontecer", diz Macri]]></title>
<link><![CDATA[https://www1.folha.uol.com.br/mercado/2018/09/acordo-adicional-da-argentina-com-fmi-esta-perto-de-acontecer-diz-macri.shtml]]></link>
<description></description>
<pubDate>Seg, 24 Set 2018 19:22:00 -0300</pubDate>
</item>
<item>
<title><![CDATA[Fernanda Melchionna: a Primavera Feminista vai derrotar Bolsonaro nas ruas e nas urnas!]]></title>
<link><![CDATA[https://agoraequesaoelas.blogfolha.uol.com.br/?p=1609]]></link>
<description></description>
<pubDate>Seg, 24 Set 2018 19:21:00 -0300</pubDate>
</item>
<item>
<title><![CDATA[Ibope: Bolsonaro estaciona na liderança; Haddad segue avançando]]></title>
<link><![CDATA[https://congressoemfoco.uol.com.br/eleicoes/ibope-bolsonaro-estaciona-na-lideranca-haddad-segue-avancando/]]></link>
<description><![CDATA[<img src='https://static.congressoemfoco.uol.com.br/2018/09/bolsonaro-haddad.jpg' align="left" /> Em nova pesquisa Ibope divulgada nesta segunda-feira (24), o candidato do PSL à Presidência, Jair Bolsonaro, continua líder com 28% das intenções de voto, sem apresentar crescimento em relação à última pesquisa, quando teve a mesma pontuação. O candidato do PT, Fernando Haddad, aproxima-se de Bolsonaro com 22%, uma diferença de 3 pontos percentuais em [?] ]]></description>
<pubDate>Seg, 24 Set 2018 19:20:08 -0300</pubDate>
</item>
<item>
<title><![CDATA[Assange chegou a renunciar a asilo do Equador, segundo carta privada]]></title>
<link><![CDATA[https://noticias.uol.com.br/ultimas-noticias/afp/2018/09/24/assange-chegou-a-renunciar-a-asilo-do-equador-segundo-carta-privada.htm]]></link>
<description><![CDATA[ Quito, 24 Set 2018 (AFP) - O fundador do WikiLeaks, Julian Assange, refugiado na embaixada equatoriana em Londres há seis anos, chegou a renunciar ao asilo concedido por Quito, segundo uma carta assinada por ele em dezembro passado à qual a AFP teve acesso. ]]></description>
<pubDate>Seg, 24 Set 2018 19:20:00 -0300</pubDate>
</item>
<item>
<title><![CDATA[Fama "A" é campeã da Primeira Divisão da Copa Cidade Alta de Futebol Suíço]]></title>
<link><![CDATA[https://tnonline.uol.com.br/noticias/apucarana/45,470926,24,09,fama-a-e-campea-da-primeira-divisao-da-copa-cidade-alta-de-futebol-suico]]></link>
<description><![CDATA[<img src='https://m1.tnonline.com.br/entre/2018/09/24/tn_563c48a591_fama-ajpg.jpg' align="left" /> om a Arena Fama lotada, a equipe da Molas Fama/Multividros "A" foi campeã neste sábado da Primeira Divisão da 10ª edição da Copa Cidade Alta de Futebol Suíço, categoria livre, ao vencer a Estamparia ... ]]></description>
<pubDate>Seg, 24 Set 2018 19:18:49 -0300</pubDate>
</item>
</channel>
</rss>
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
{
"feed": {
"items": [
{
"title": "v3.9.0",
"link": "/gulpjs/gulp/releases/tag/v3.9.0",
"pubDate": "2015-06-01T21:49:41.000Z",
"author": "contra",
"content": "<p>3.9.0</p>",
"contentSnippet": "3.9.0",
"id": "tag:github.com,2008:Repository/11167738/v3.9.0",
"isoDate": "2015-06-01T21:49:41.000Z"
},
{
"title": "v3.8.11",
"link": "/gulpjs/gulp/releases/tag/v3.8.11",
"pubDate": "2015-02-09T20:37:28.000Z",
"author": "contra",
"content": "<p>3.8.11</p>",
"contentSnippet": "3.8.11",
"id": "tag:github.com,2008:Repository/11167738/v3.8.11",
"isoDate": "2015-02-09T20:37:28.000Z"
},
{
"title": "v3.8.10",
"link": "/gulpjs/gulp/releases/tag/v3.8.10",
"pubDate": "2014-11-04T00:11:30.000Z",
"author": "contra",
"content": "<p>3.8.10</p>",
"contentSnippet": "3.8.10",
"id": "tag:github.com,2008:Repository/11167738/v3.8.10",
"isoDate": "2014-11-04T00:11:30.000Z"
},
{
"title": "v3.8.9",
"link": "/gulpjs/gulp/releases/tag/v3.8.9",
"pubDate": "2014-10-22T06:55:20.000Z",
"author": "contra",
"content": "<p>3.8.9</p>",
"contentSnippet": "3.8.9",
"id": "tag:github.com,2008:Repository/11167738/v3.8.9",
"isoDate": "2014-10-22T06:55:20.000Z"
},
{
"title": "v3.8.8",
"link": "/gulpjs/gulp/releases/tag/v3.8.8",
"pubDate": "2014-09-07T20:20:11.000Z",
"author": "contra",
"content": "<p>3.8.8</p>",
"contentSnippet": "3.8.8",
"id": "tag:github.com,2008:Repository/11167738/v3.8.8",
"isoDate": "2014-09-07T20:20:11.000Z"
},
{
"title": "v3.8.7",
"link": "/gulpjs/gulp/releases/tag/v3.8.7",
"pubDate": "2014-08-02T04:58:19.000Z",
"author": "contra",
"content": "<p>3.8.7</p>",
"contentSnippet": "3.8.7",
"id": "tag:github.com,2008:Repository/11167738/v3.8.7",
"isoDate": "2014-08-02T04:58:19.000Z"
},
{
"title": "v3.8.6",
"link": "/gulpjs/gulp/releases/tag/v3.8.6",
"pubDate": "2014-07-09T22:06:50.000Z",
"author": "contra",
"content": "<p>3.8.6</p>",
"contentSnippet": "3.8.6",
"id": "tag:github.com,2008:Repository/11167738/v3.8.6",
"isoDate": "2014-07-09T22:06:50.000Z"
},
{
"title": "v3.8.5",
"link": "/gulpjs/gulp/releases/tag/v3.8.5",
"pubDate": "2014-06-27T06:53:54.000Z",
"author": "contra",
"content": "<p>3.8.5</p>",
"contentSnippet": "3.8.5",
"id": "tag:github.com,2008:Repository/11167738/v3.8.5",
"isoDate": "2014-06-27T06:53:54.000Z"
},
{
"title": "v3.8.4",
"link": "/gulpjs/gulp/releases/tag/v3.8.4",
"pubDate": "2014-06-27T06:38:43.000Z",
"author": "contra",
"content": "<p>3.8.4</p>",
"contentSnippet": "3.8.4",
"id": "tag:github.com,2008:Repository/11167738/v3.8.4",
"isoDate": "2014-06-27T06:38:43.000Z"
},
{
"title": "v3.8.3",
"link": "/gulpjs/gulp/releases/tag/v3.8.3",
"pubDate": "2014-06-26T21:17:51.000Z",
"author": "contra",
"content": "<p>3.8.3</p>",
"contentSnippet": "3.8.3",
"id": "tag:github.com,2008:Repository/11167738/v3.8.3",
"isoDate": "2014-06-26T21:17:51.000Z"
}
],
"link": "https://github.com/gulpjs/gulp/releases",
"feedUrl": "https://github.com/gulpjs/gulp/releases.atom",
"title": "Release notes from gulp",
"lastBuildDate": "2015-06-01T23:49:41+02:00"
}
}
\ No newline at end of file
This diff is collapsed. Click to expand it.
{
"feed": {
"items": [
{
"title": "The First Item",
"link": "http://www.oreilly.com/example/001.html",
"enclosure": {
"url": "http://www.oreilly.com/001.mp3",
"length": "54321",
"type": "audio/mpeg"
},
"content": "This is the first item.",
"contentSnippet": "This is the first item.",
"categories": [
{
"_": "Business/Industries/Publishing/Publishers/Nonfiction/",
"$": {
"domain": "http://www.dmoz.org"
}
}
]
},
{
"title": "The Second Item",
"link": "http://www.oreilly.com/example/002.html",
"enclosure": {
"url": "http://www.oreilly.com/002.mp3",
"length": "54321",
"type": "audio/mpeg"
},
"content": "This is the second item.",
"contentSnippet": "This is the second item.",
"categories": [
{
"_": "Business/Industries/Publishing/Publishers/Nonfiction/",
"$": {
"domain": "http://www.dmoz.org"
}
}
]
}
],
"title": "RSS0.92 Example",
"description": "This is an example RSS0.91 feed",
"pubDate": "03 Apr 02 1500 GMT",
"webMaster": "webmaster@oreilly.com",
"managingEditor": "editor@oreilly.com",
"link": "http://www.oreilly.com/example/index.html",
"language": "en-gb",
"copyright": "Copyright 2002, Oreilly and Associates.",
"lastBuildDate": "03 Apr 02 1500 GMT",
"rating": "5"
}
}
\ No newline at end of file
{
"feed": {
"items": [
{
"creator": "tobi",
"date": "2016-05-04T06:53:45Z",
"title": "My first Instant Article",
"link": "https://localhost:8000",
"pubDate": "Wed, 04 May 2016 06:53:45 GMT",
"content:encoded": "<b>Lorem</b> ipsum",
"dc:creator": "tobi",
"dc:date": "2016-05-04T06:53:45Z",
"content": "Lorem ipsum",
"contentSnippet": "Lorem ipsum",
"guid": "https://localhost:8000",
"isoDate": "2016-05-04T06:53:45.000Z"
}
],
"title": "Instant Article Test",
"description": "1, 2, 1, 2… check the mic!",
"pubDate": "Fri, 13 May 2016 15:14:05 GMT",
"link": "https://localhost:8000",
"language": "en"
}
}
\ No newline at end of file
This diff could not be displayed because it is too large.
{
"feed": {
"items": [
{
"id": "tag:github.com,2008:Repository/11167738/v3.9.0"
}
]
}
}
\ No newline at end of file
{
"feed": {
"items": [
{
"creator": "foobar@gmail.com",
"title": "FAQ for Narro",
"link": "https://www.narro.co/article/54e703933058540300000069",
"pubDate": "Fri, 20 Feb 2015 09:51:15 UTC",
"author": "foobar@gmail.com",
"enclosure": {
"url": "https://s3.amazonaws.com/nareta-articles/audio/54d046c293f79c0300000003/7e2d2b00-a945-441a-f49b-063786a319a4.mp3",
"length": "74",
"type": "audio/mpeg"
},
"content": "Listen to your reading list anywhere. Narro will take your bookmarked articles and read them back to you as a podcast.<br/> http://www.narro.co/faq<br/> <ul class=\"linkList\"></ul>",
"contentSnippet": "Listen to your reading list anywhere. Narro will take your bookmarked articles and read them back to you as a podcast. http://www.narro.co/faq",
"guid": "https://www.narro.co/article/54e703933058540300000069",
"isoDate": "2015-02-20T09:51:15.000Z",
"itunes": {
"author": "foobar@gmail.com",
"subtitle": "FAQ for Narro",
"summary": "Listen to your reading list anywhere. Narro will take your bookmarked articles and read them back to you as a podcast. ... http://www.narro.co/faq ... <ul class=\"linkList\"></ul>",
"explicit": "no",
"duration": "74",
"image": "http://example.com/someImage.jpg"
}
}
],
"feedUrl": "http://on.narro.co/f",
"title": "foobar on Narro",
"description": "foobar uses Narro to create a podcast of articles transcribed to audio.",
"pubDate": "Fri, 08 Jul 2016 13:40:00 UTC",
"webMaster": "josh@narro.co",
"managingEditor": "foobar@gmail.com",
"generator": "gopod - http://github.com/jbckmn/gopod",
"link": "http://on.narro.co/f",
"language": "en",
"copyright": "All article content copyright of respective source authors.",
"ttl": "20",
"itunes": {
"image": "https://www.narro.co/images/narro-icon-lg.png",
"owner": {
"name": "foobar",
"email": "foobar@gmail.com"
},
"author": "foobar@gmail.com",
"subtitle": "foobar uses Narro to create a podcast of articles transcribed to audio.",
"summary": "foobar uses Narro to create a podcast of articles transcribed to audio.",
"explicit": "no"
}
}
}
\ No newline at end of file
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
"use strict";
var fs = require('fs');
var HTTP = require('http');
var Parser = require('../index.js');
var Expect = require('chai').expect;
var IN_DIR = __dirname + '/input';
var OUT_DIR = __dirname + '/output';
describe('Parser', function() {
var testParseForFile = function(name, ext, options, done) {
if (typeof done === 'undefined') {
done = options;
options = {};
}
let parser = new Parser(options);
let xml = fs.readFileSync(IN_DIR + '/' + name + '.' + ext, 'utf8');
parser.parseString(xml, function(err, parsed) {
if (err) console.log(err);
Expect(err).to.equal(null);
if (process.env.WRITE_GOLDEN) {
fs.writeFileSync(OUT_DIR + '/' + name + '.json', JSON.stringify({feed: parsed}, null, 2));
} else {
var expected = fs.readFileSync(OUT_DIR + '/' + name + '.json', 'utf8')
expected = JSON.parse(expected);
Expect({feed: parsed}).to.deep.equal(expected);
}
done();
})
}
it('should parse Reddit', function(done) {
testParseForFile('reddit', 'rss', done);
})
it('should parse sciencemag.org (RSS 1.0)', function(done) {
testParseForFile('rss-1', 'rss', done);
})
it('should parse craigslist (RSS 1.0)', function(done) {
testParseForFile('craigslist', 'rss', done);
})
it('should parse atom', function(done) {
testParseForFile('reddit-atom', 'rss', done);
})
it('should parse atom feed', function(done) {
testParseForFile('gulp-atom', 'atom', done);
})
it('should parse reddits new feed', function(done) {
testParseForFile('reddit-home', 'rss', done);
})
it('should parse with missing fields', function(done) {
testParseForFile('missing-fields', 'atom', done)
})
it('should parse heise', function(done) {
testParseForFile('heise', 'atom', done);
})
it('should parse heraldsun', function(done) {
testParseForFile('heraldsun', 'rss', done);
});
it('should parse UOL Noticias', function(done) {
testParseForFile('uolNoticias', 'rss', { defaultRSS: 2.0 }, done);
});
it('should NOT parse UOL Noticias, if no default RSS is provided', function(done) {
function willFail() {
testParseForFile('uolNoticias', 'rss', done);
}
Expect(willFail).to.throw;
done();
});
it('should parse Instant Article', function(done) {
testParseForFile('instant-article', 'rss', done);
});
it('should parse Feedburner', function(done) {
testParseForFile('feedburner', 'atom', done);
});
it('should parse podcasts', function(done) {
testParseForFile('narro', 'rss', done);
});
it('should parse multiple links', function(done) {
testParseForFile('many-links', 'rss', done);
});
it('should pass xml2js options', function(done) {
testParseForFile('xml2js-options', 'rss', {xml2js: {emptyTag: 'EMPTY'}}, done);
});
it('should throw error for unrecognized', function(done) {
let parser = new Parser();
let xml = fs.readFileSync(__dirname + '/input/unrecognized.rss', 'utf8');
parser.parseString(xml, function(err, parsed) {
Expect(err.message).to.contain('Feed not recognized as RSS');
done();
});
});
it('should omit iTunes image if none available during decoration', function(done) {
const rssFeedWithMissingImage = __dirname + '/input/itunes-missing-image.rss';
const xml = fs.readFileSync(rssFeedWithMissingImage, 'utf8');
let parser = new Parser();
parser.parseString(xml, function(err, parsed) {
Expect(err).to.be.null;
Expect(parsed).to.not.have.deep.property('feed.itunes.image');
done();
});
});
it('should parse custom fields', function(done) {
var options = {
customFields: {
feed: ['language', 'copyright', 'nested-field'],
item: ['subtitle']
}
};
testParseForFile('customfields', 'rss', options, done);
});
it('should parse Atom feed custom fields', function(done) {
var options = {
customFields: {
feed: ['totalViews'],
item: ['media:group']
}
};
testParseForFile('atom-customfields', 'atom', options, done);
});
it('should parse sibling custom fields', function(done) {
var options = {
customFields: {
item: [['media:content', 'media:content', {keepArray: true}]]
}
};
testParseForFile('guardian', 'rss', options, done);
});
it('should parse URL', function(done) {
var INPUT_FILE = __dirname + '/input/reddit.rss';
var OUTPUT_FILE = __dirname + '/output/reddit.json';
var server = HTTP.createServer(function(req, res) {
var file = fs.createReadStream(INPUT_FILE, 'utf8');
file.pipe(res);
});
server.listen(function() {
var port = server.address().port;
var url = 'http://localhost:' + port;
let parser = new Parser();
parser.parseURL(url, function(err, parsed) {
Expect(err).to.equal(null);
if (process.env.WRITE_GOLDEN) {
fs.writeFileSync(OUTPUT_FILE, JSON.stringify({feed: parsed}, null, 2));
} else {
var expected = JSON.parse(fs.readFileSync(OUTPUT_FILE, 'utf8'));
Expect({feed: parsed}).to.deep.equal(expected);
}
server.close();
done();
});
});
});
it('should use proper encoding', function(done) {
var INPUT_FILE = __dirname + '/input/encoding.rss';
var OUTPUT_FILE = __dirname + '/output/encoding.json';
var ENCODING = 'latin1';
var server = HTTP.createServer(function(req, res) {
res.setHeader('Content-Type', 'text/xml; charset=' + ENCODING)
var file = fs.readFileSync(INPUT_FILE, ENCODING);
res.end(file, ENCODING);
});
server.listen(function() {
var port = server.address().port;
var url = 'http://localhost:' + port;
var parser = new Parser();
parser.parseURL(url, function(err, parsed) {
Expect(err).to.equal(null);
if (process.env.WRITE_GOLDEN) {
fs.writeFileSync(OUTPUT_FILE, JSON.stringify({feed: parsed}, null, 2), {encoding: ENCODING});
} else {
var expected = JSON.parse(fs.readFileSync(OUTPUT_FILE, ENCODING));
Expect({feed: parsed}).to.deep.equal(expected);
}
server.close();
done();
})
})
})
})
var webpack = require("webpack");
module.exports = {
entry: {
"rss-parser": "./browser.js"
},
output: {
path: __dirname,
filename: "dist/[name].min.js"
},
resolve: {
extensions: ['.js']
},
devtool: 'source-map',
module: {
loaders: [{
test: /\.js$/,
loader: 'babel-loader?presets[]=env',
}]
},
node: {
fs: "empty"
}
}
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
====
`String.fromCodePoint` by Mathias Bynens used according to terms of MIT
License, as follows:
Copyright Mathias Bynens <https://mathiasbynens.be/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# sax js
A sax-style parser for XML and HTML.
Designed with [node](http://nodejs.org/) in mind, but should work fine in
the browser or other CommonJS implementations.
## What This Is
* A very simple tool to parse through an XML string.
* A stepping stone to a streaming HTML parser.
* A handy way to deal with RSS and other mostly-ok-but-kinda-broken XML
docs.
## What This Is (probably) Not
* An HTML Parser - That's a fine goal, but this isn't it. It's just
XML.
* A DOM Builder - You can use it to build an object model out of XML,
but it doesn't do that out of the box.
* XSLT - No DOM = no querying.
* 100% Compliant with (some other SAX implementation) - Most SAX
implementations are in Java and do a lot more than this does.
* An XML Validator - It does a little validation when in strict mode, but
not much.
* A Schema-Aware XSD Thing - Schemas are an exercise in fetishistic
masochism.
* A DTD-aware Thing - Fetching DTDs is a much bigger job.
## Regarding `<!DOCTYPE`s and `<!ENTITY`s
The parser will handle the basic XML entities in text nodes and attribute
values: `&amp; &lt; &gt; &apos; &quot;`. It's possible to define additional
entities in XML by putting them in the DTD. This parser doesn't do anything
with that. If you want to listen to the `ondoctype` event, and then fetch
the doctypes, and read the entities and add them to `parser.ENTITIES`, then
be my guest.
Unknown entities will fail in strict mode, and in loose mode, will pass
through unmolested.
## Usage
```javascript
var sax = require("./lib/sax"),
strict = true, // set to false for html-mode
parser = sax.parser(strict);
parser.onerror = function (e) {
// an error happened.
};
parser.ontext = function (t) {
// got some text. t is the string of text.
};
parser.onopentag = function (node) {
// opened a tag. node has "name" and "attributes"
};
parser.onattribute = function (attr) {
// an attribute. attr has "name" and "value"
};
parser.onend = function () {
// parser stream is done, and ready to have more stuff written to it.
};
parser.write('<xml>Hello, <who name="world">world</who>!</xml>').close();
// stream usage
// takes the same options as the parser
var saxStream = require("sax").createStream(strict, options)
saxStream.on("error", function (e) {
// unhandled errors will throw, since this is a proper node
// event emitter.
console.error("error!", e)
// clear the error
this._parser.error = null
this._parser.resume()
})
saxStream.on("opentag", function (node) {
// same object as above
})
// pipe is supported, and it's readable/writable
// same chunks coming in also go out.
fs.createReadStream("file.xml")
.pipe(saxStream)
.pipe(fs.createWriteStream("file-copy.xml"))
```
## Arguments
Pass the following arguments to the parser function. All are optional.
`strict` - Boolean. Whether or not to be a jerk. Default: `false`.
`opt` - Object bag of settings regarding string formatting. All default to `false`.
Settings supported:
* `trim` - Boolean. Whether or not to trim text and comment nodes.
* `normalize` - Boolean. If true, then turn any whitespace into a single
space.
* `lowercase` - Boolean. If true, then lowercase tag names and attribute names
in loose mode, rather than uppercasing them.
* `xmlns` - Boolean. If true, then namespaces are supported.
* `position` - Boolean. If false, then don't track line/col/position.
* `strictEntities` - Boolean. If true, only parse [predefined XML
entities](http://www.w3.org/TR/REC-xml/#sec-predefined-ent)
(`&amp;`, `&apos;`, `&gt;`, `&lt;`, and `&quot;`)
## Methods
`write` - Write bytes onto the stream. You don't have to do this all at
once. You can keep writing as much as you want.
`close` - Close the stream. Once closed, no more data may be written until
it is done processing the buffer, which is signaled by the `end` event.
`resume` - To gracefully handle errors, assign a listener to the `error`
event. Then, when the error is taken care of, you can call `resume` to
continue parsing. Otherwise, the parser will not continue while in an error
state.
## Members
At all times, the parser object will have the following members:
`line`, `column`, `position` - Indications of the position in the XML
document where the parser currently is looking.
`startTagPosition` - Indicates the position where the current tag starts.
`closed` - Boolean indicating whether or not the parser can be written to.
If it's `true`, then wait for the `ready` event to write again.
`strict` - Boolean indicating whether or not the parser is a jerk.
`opt` - Any options passed into the constructor.
`tag` - The current tag being dealt with.
And a bunch of other stuff that you probably shouldn't touch.
## Events
All events emit with a single argument. To listen to an event, assign a
function to `on<eventname>`. Functions get executed in the this-context of
the parser object. The list of supported events are also in the exported
`EVENTS` array.
When using the stream interface, assign handlers using the EventEmitter
`on` function in the normal fashion.
`error` - Indication that something bad happened. The error will be hanging
out on `parser.error`, and must be deleted before parsing can continue. By
listening to this event, you can keep an eye on that kind of stuff. Note:
this happens *much* more in strict mode. Argument: instance of `Error`.
`text` - Text node. Argument: string of text.
`doctype` - The `<!DOCTYPE` declaration. Argument: doctype string.
`processinginstruction` - Stuff like `<?xml foo="blerg" ?>`. Argument:
object with `name` and `body` members. Attributes are not parsed, as
processing instructions have implementation dependent semantics.
`sgmldeclaration` - Random SGML declarations. Stuff like `<!ENTITY p>`
would trigger this kind of event. This is a weird thing to support, so it
might go away at some point. SAX isn't intended to be used to parse SGML,
after all.
`opentagstart` - Emitted immediately when the tag name is available,
but before any attributes are encountered. Argument: object with a
`name` field and an empty `attributes` set. Note that this is the
same object that will later be emitted in the `opentag` event.
`opentag` - An opening tag. Argument: object with `name` and `attributes`.
In non-strict mode, tag names are uppercased, unless the `lowercase`
option is set. If the `xmlns` option is set, then it will contain
namespace binding information on the `ns` member, and will have a
`local`, `prefix`, and `uri` member.
`closetag` - A closing tag. In loose mode, tags are auto-closed if their
parent closes. In strict mode, well-formedness is enforced. Note that
self-closing tags will have `closeTag` emitted immediately after `openTag`.
Argument: tag name.
`attribute` - An attribute node. Argument: object with `name` and `value`.
In non-strict mode, attribute names are uppercased, unless the `lowercase`
option is set. If the `xmlns` option is set, it will also contains namespace
information.
`comment` - A comment node. Argument: the string of the comment.
`opencdata` - The opening tag of a `<![CDATA[` block.
`cdata` - The text of a `<![CDATA[` block. Since `<![CDATA[` blocks can get
quite large, this event may fire multiple times for a single block, if it
is broken up into multiple `write()`s. Argument: the string of random
character data.
`closecdata` - The closing tag (`]]>`) of a `<![CDATA[` block.
`opennamespace` - If the `xmlns` option is set, then this event will
signal the start of a new namespace binding.
`closenamespace` - If the `xmlns` option is set, then this event will
signal the end of a namespace binding.
`end` - Indication that the closed stream has ended.
`ready` - Indication that the stream has reset, and is ready to be written
to.
`noscript` - In non-strict mode, `<script>` tags trigger a `"script"`
event, and their contents are not checked for special xml characters.
If you pass `noscript: true`, then this behavior is suppressed.
## Reporting Problems
It's best to write a failing test if you find an issue. I will always
accept pull requests with failing tests if they demonstrate intended
behavior, but it is very hard to figure out what issue you're describing
without a test. Writing a test is also the best way for you yourself
to figure out if you really understand the issue you think you have with
sax-js.
This diff is collapsed. Click to expand it.
{
"_from": "sax@>=0.6.0",
"_id": "sax@1.2.4",
"_inBundle": false,
"_integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"_location": "/sax",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "sax@>=0.6.0",
"name": "sax",
"escapedName": "sax",
"rawSpec": ">=0.6.0",
"saveSpec": null,
"fetchSpec": ">=0.6.0"
},
"_requiredBy": [
"/xml2js"
],
"_resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"_shasum": "2816234e2378bddc4e5354fab5caa895df7100d9",
"_spec": "sax@>=0.6.0",
"_where": "C:\\Users\\정민채\\Desktop\\TermProject\\2017104024정민혁KakaoBot\\node_modules\\xml2js",
"author": {
"name": "Isaac Z. Schlueter",
"email": "i@izs.me",
"url": "http://blog.izs.me/"
},
"bugs": {
"url": "https://github.com/isaacs/sax-js/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "An evented streaming XML parser in JavaScript",
"devDependencies": {
"standard": "^8.6.0",
"tap": "^10.5.1"
},
"files": [
"lib/sax.js",
"LICENSE",
"README.md"
],
"homepage": "https://github.com/isaacs/sax-js#readme",
"license": "ISC",
"main": "lib/sax.js",
"name": "sax",
"repository": {
"type": "git",
"url": "git://github.com/isaacs/sax-js.git"
},
"scripts": {
"postpublish": "git push origin --all; git push origin --tags",
"posttest": "standard -F test/*.js lib/*.js",
"postversion": "npm publish",
"preversion": "npm test",
"test": "tap test/*.js --cov -j4"
},
"version": "1.2.4"
}
Copyright 2010, 2011, 2012, 2013. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
This diff is collapsed. Click to expand it.
// Generated by CoffeeScript 1.12.7
(function() {
"use strict";
exports.stripBOM = function(str) {
if (str[0] === '\uFEFF') {
return str.substring(1);
} else {
return str;
}
};
}).call(this);
// Generated by CoffeeScript 1.12.7
(function() {
"use strict";
var builder, defaults, escapeCDATA, requiresCDATA, wrapCDATA,
hasProp = {}.hasOwnProperty;
builder = require('xmlbuilder');
defaults = require('./defaults').defaults;
requiresCDATA = function(entry) {
return typeof entry === "string" && (entry.indexOf('&') >= 0 || entry.indexOf('>') >= 0 || entry.indexOf('<') >= 0);
};
wrapCDATA = function(entry) {
return "<![CDATA[" + (escapeCDATA(entry)) + "]]>";
};
escapeCDATA = function(entry) {
return entry.replace(']]>', ']]]]><![CDATA[>');
};
exports.Builder = (function() {
function Builder(opts) {
var key, ref, value;
this.options = {};
ref = defaults["0.2"];
for (key in ref) {
if (!hasProp.call(ref, key)) continue;
value = ref[key];
this.options[key] = value;
}
for (key in opts) {
if (!hasProp.call(opts, key)) continue;
value = opts[key];
this.options[key] = value;
}
}
Builder.prototype.buildObject = function(rootObj) {
var attrkey, charkey, render, rootElement, rootName;
attrkey = this.options.attrkey;
charkey = this.options.charkey;
if ((Object.keys(rootObj).length === 1) && (this.options.rootName === defaults['0.2'].rootName)) {
rootName = Object.keys(rootObj)[0];
rootObj = rootObj[rootName];
} else {
rootName = this.options.rootName;
}
render = (function(_this) {
return function(element, obj) {
var attr, child, entry, index, key, value;
if (typeof obj !== 'object') {
if (_this.options.cdata && requiresCDATA(obj)) {
element.raw(wrapCDATA(obj));
} else {
element.txt(obj);
}
} else if (Array.isArray(obj)) {
for (index in obj) {
if (!hasProp.call(obj, index)) continue;
child = obj[index];
for (key in child) {
entry = child[key];
element = render(element.ele(key), entry).up();
}
}
} else {
for (key in obj) {
if (!hasProp.call(obj, key)) continue;
child = obj[key];
if (key === attrkey) {
if (typeof child === "object") {
for (attr in child) {
value = child[attr];
element = element.att(attr, value);
}
}
} else if (key === charkey) {
if (_this.options.cdata && requiresCDATA(child)) {
element = element.raw(wrapCDATA(child));
} else {
element = element.txt(child);
}
} else if (Array.isArray(child)) {
for (index in child) {
if (!hasProp.call(child, index)) continue;
entry = child[index];
if (typeof entry === 'string') {
if (_this.options.cdata && requiresCDATA(entry)) {
element = element.ele(key).raw(wrapCDATA(entry)).up();
} else {
element = element.ele(key, entry).up();
}
} else {
element = render(element.ele(key), entry).up();
}
}
} else if (typeof child === "object") {
element = render(element.ele(key), child).up();
} else {
if (typeof child === 'string' && _this.options.cdata && requiresCDATA(child)) {
element = element.ele(key).raw(wrapCDATA(child)).up();
} else {
if (child == null) {
child = '';
}
element = element.ele(key, child.toString()).up();
}
}
}
}
return element;
};
})(this);
rootElement = builder.create(rootName, this.options.xmldec, this.options.doctype, {
headless: this.options.headless,
allowSurrogateChars: this.options.allowSurrogateChars
});
return render(rootElement, rootObj).end(this.options.renderOpts);
};
return Builder;
})();
}).call(this);
// Generated by CoffeeScript 1.12.7
(function() {
exports.defaults = {
"0.1": {
explicitCharkey: false,
trim: true,
normalize: true,
normalizeTags: false,
attrkey: "@",
charkey: "#",
explicitArray: false,
ignoreAttrs: false,
mergeAttrs: false,
explicitRoot: false,
validator: null,
xmlns: false,
explicitChildren: false,
childkey: '@@',
charsAsChildren: false,
includeWhiteChars: false,
async: false,
strict: true,
attrNameProcessors: null,
attrValueProcessors: null,
tagNameProcessors: null,
valueProcessors: null,
emptyTag: ''
},
"0.2": {
explicitCharkey: false,
trim: false,
normalize: false,
normalizeTags: false,
attrkey: "$",
charkey: "_",
explicitArray: true,
ignoreAttrs: false,
mergeAttrs: false,
explicitRoot: true,
validator: null,
xmlns: false,
explicitChildren: false,
preserveChildrenOrder: false,
childkey: '$$',
charsAsChildren: false,
includeWhiteChars: false,
async: false,
strict: true,
attrNameProcessors: null,
attrValueProcessors: null,
tagNameProcessors: null,
valueProcessors: null,
rootName: 'root',
xmldec: {
'version': '1.0',
'encoding': 'UTF-8',
'standalone': true
},
doctype: null,
renderOpts: {
'pretty': true,
'indent': ' ',
'newline': '\n'
},
headless: false,
chunkSize: 10000,
emptyTag: '',
cdata: false
}
};
}).call(this);
This diff is collapsed. Click to expand it.
// Generated by CoffeeScript 1.12.7
(function() {
"use strict";
var prefixMatch;
prefixMatch = new RegExp(/(?!xmlns)^.*:/);
exports.normalize = function(str) {
return str.toLowerCase();
};
exports.firstCharLowerCase = function(str) {
return str.charAt(0).toLowerCase() + str.slice(1);
};
exports.stripPrefix = function(str) {
return str.replace(prefixMatch, '');
};
exports.parseNumbers = function(str) {
if (!isNaN(str)) {
str = str % 1 === 0 ? parseInt(str, 10) : parseFloat(str);
}
return str;
};
exports.parseBooleans = function(str) {
if (/^(?:true|false)$/i.test(str)) {
str = str.toLowerCase() === 'true';
}
return str;
};
}).call(this);
// Generated by CoffeeScript 1.12.7
(function() {
"use strict";
var builder, defaults, parser, processors,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
defaults = require('./defaults');
builder = require('./builder');
parser = require('./parser');
processors = require('./processors');
exports.defaults = defaults.defaults;
exports.processors = processors;
exports.ValidationError = (function(superClass) {
extend(ValidationError, superClass);
function ValidationError(message) {
this.message = message;
}
return ValidationError;
})(Error);
exports.Builder = builder.Builder;
exports.Parser = parser.Parser;
exports.parseString = parser.parseString;
}).call(this);
{
"_from": "xml2js@^0.4.19",
"_id": "xml2js@0.4.19",
"_inBundle": false,
"_integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
"_location": "/xml2js",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "xml2js@^0.4.19",
"name": "xml2js",
"escapedName": "xml2js",
"rawSpec": "^0.4.19",
"saveSpec": null,
"fetchSpec": "^0.4.19"
},
"_requiredBy": [
"/rss-parser"
],
"_resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
"_shasum": "686c20f213209e94abf0d1bcf1efaa291c7827a7",
"_spec": "xml2js@^0.4.19",
"_where": "C:\\Users\\정민채\\Desktop\\TermProject\\2017104024정민혁KakaoBot\\node_modules\\rss-parser",
"author": {
"name": "Marek Kubica",
"email": "marek@xivilization.net",
"url": "https://xivilization.net"
},
"bugs": {
"url": "https://github.com/Leonidas-from-XIV/node-xml2js/issues"
},
"bundleDependencies": false,
"contributors": [
{
"name": "maqr",
"email": "maqr.lollerskates@gmail.com",
"url": "https://github.com/maqr"
},
{
"name": "Ben Weaver",
"url": "http://benweaver.com/"
},
{
"name": "Jae Kwon",
"url": "https://github.com/jaekwon"
},
{
"name": "Jim Robert"
},
{
"name": "Ștefan Rusu",
"url": "http://www.saltwaterc.eu/"
},
{
"name": "Carter Cole",
"email": "carter.cole@cartercole.com",
"url": "http://cartercole.com/"
},
{
"name": "Kurt Raschke",
"email": "kurt@kurtraschke.com",
"url": "http://www.kurtraschke.com/"
},
{
"name": "Contra",
"email": "contra@australia.edu",
"url": "https://github.com/Contra"
},
{
"name": "Marcelo Diniz",
"email": "marudiniz@gmail.com",
"url": "https://github.com/mdiniz"
},
{
"name": "Michael Hart",
"url": "https://github.com/mhart"
},
{
"name": "Zachary Scott",
"email": "zachary@zacharyscott.net",
"url": "http://zacharyscott.net/"
},
{
"name": "Raoul Millais",
"url": "https://github.com/raoulmillais"
},
{
"name": "Salsita Software",
"url": "http://www.salsitasoft.com/"
},
{
"name": "Mike Schilling",
"email": "mike@emotive.com",
"url": "http://www.emotive.com/"
},
{
"name": "Jackson Tian",
"email": "shyvo1987@gmail.com",
"url": "http://weibo.com/shyvo"
},
{
"name": "Mikhail Zyatin",
"email": "mikhail.zyatin@gmail.com",
"url": "https://github.com/Sitin"
},
{
"name": "Chris Tavares",
"email": "ctavares@microsoft.com",
"url": "https://github.com/christav"
},
{
"name": "Frank Xu",
"email": "yyfrankyy@gmail.com",
"url": "http://f2e.us/"
},
{
"name": "Guido D'Albore",
"email": "guido@bitstorm.it",
"url": "http://www.bitstorm.it/"
},
{
"name": "Jack Senechal",
"url": "http://jacksenechal.com/"
},
{
"name": "Matthias Hölzl",
"email": "tc@xantira.com",
"url": "https://github.com/hoelzl"
},
{
"name": "Camille Reynders",
"email": "info@creynders.be",
"url": "http://www.creynders.be/"
},
{
"name": "Taylor Gautier",
"url": "https://github.com/tsgautier"
},
{
"name": "Todd Bryan",
"url": "https://github.com/toddrbryan"
},
{
"name": "Leore Avidar",
"email": "leore.avidar@gmail.com",
"url": "http://leoreavidar.com/"
},
{
"name": "Dave Aitken",
"email": "dave.aitken@gmail.com",
"url": "http://www.actionshrimp.com/"
},
{
"name": "Shaney Orrowe",
"email": "shaney.orrowe@practiceweb.co.uk"
},
{
"name": "Candle",
"email": "candle@candle.me.uk"
},
{
"name": "Jess Telford",
"email": "hi@jes.st",
"url": "http://jes.st"
},
{
"name": "Tom Hughes",
"email": "<tom@compton.nu",
"url": "http://compton.nu/"
},
{
"name": "Piotr Rochala",
"url": "http://rocha.la/"
},
{
"name": "Michael Avila",
"url": "https://github.com/michaelavila"
},
{
"name": "Ryan Gahl",
"url": "https://github.com/ryedin"
},
{
"name": "Eric Laberge",
"email": "e.laberge@gmail.com",
"url": "https://github.com/elaberge"
},
{
"name": "Benjamin E. Coe",
"email": "ben@npmjs.com",
"url": "https://twitter.com/benjamincoe"
},
{
"name": "Stephen Cresswell",
"url": "https://github.com/cressie176"
},
{
"name": "Pascal Ehlert",
"email": "pascal@hacksrus.net",
"url": "http://www.hacksrus.net/"
},
{
"name": "Tom Spencer",
"email": "fiznool@gmail.com",
"url": "http://fiznool.com/"
},
{
"name": "Tristian Flanagan",
"email": "tflanagan@datacollaborative.com",
"url": "https://github.com/tflanagan"
},
{
"name": "Tim Johns",
"email": "timjohns@yahoo.com",
"url": "https://github.com/TimJohns"
},
{
"name": "Bogdan Chadkin",
"email": "trysound@yandex.ru",
"url": "https://github.com/TrySound"
},
{
"name": "David Wood",
"email": "david.p.wood@gmail.com",
"url": "http://codesleuth.co.uk/"
},
{
"name": "Nicolas Maquet",
"url": "https://github.com/nmaquet"
},
{
"name": "Lovell Fuller",
"url": "http://lovell.info/"
},
{
"name": "d3adc0d3",
"url": "https://github.com/d3adc0d3"
}
],
"dependencies": {
"sax": ">=0.6.0",
"xmlbuilder": "~9.0.1"
},
"deprecated": false,
"description": "Simple XML to JavaScript object converter.",
"devDependencies": {
"coffee-script": ">=1.10.0",
"coveralls": "^2.11.2",
"diff": ">=1.0.8",
"docco": ">=0.6.2",
"nyc": ">=2.2.1",
"zap": ">=0.2.9"
},
"directories": {
"lib": "./lib"
},
"files": [
"lib"
],
"homepage": "https://github.com/Leonidas-from-XIV/node-xml2js",
"keywords": [
"xml",
"json"
],
"license": "MIT",
"main": "./lib/xml2js",
"name": "xml2js",
"repository": {
"type": "git",
"url": "git+https://github.com/Leonidas-from-XIV/node-xml2js.git"
},
"scripts": {
"coverage": "nyc npm test && nyc report",
"coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls",
"test": "zap"
},
"version": "0.4.19"
}
.travis.yml
src
test
perf
coverage
This diff is collapsed. Click to expand it.
The MIT License (MIT)
Copyright (c) 2013 Ozgur Ozcitak
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# xmlbuilder-js
An XML builder for [node.js](https://nodejs.org/) similar to
[java-xmlbuilder](https://github.com/jmurty/java-xmlbuilder).
[![License](http://img.shields.io/npm/l/xmlbuilder.svg?style=flat-square)](http://opensource.org/licenses/MIT)
[![NPM Version](http://img.shields.io/npm/v/xmlbuilder.svg?style=flat-square)](https://npmjs.com/package/xmlbuilder)
[![NPM Downloads](https://img.shields.io/npm/dm/xmlbuilder.svg?style=flat-square)](https://npmjs.com/package/xmlbuilder)
[![Build Status](http://img.shields.io/travis/oozcitak/xmlbuilder-js.svg?style=flat-square)](http://travis-ci.org/oozcitak/xmlbuilder-js)
[![Dev Dependency Status](http://img.shields.io/david/dev/oozcitak/xmlbuilder-js.svg?style=flat-square)](https://david-dm.org/oozcitak/xmlbuilder-js)
[![Code Coverage](https://img.shields.io/coveralls/oozcitak/xmlbuilder-js.svg?style=flat-square)](https://coveralls.io/github/oozcitak/xmlbuilder-js)
### Installation:
``` sh
npm install xmlbuilder
```
### Usage:
``` js
var builder = require('xmlbuilder');
var xml = builder.create('root')
.ele('xmlbuilder')
.ele('repo', {'type': 'git'}, 'git://github.com/oozcitak/xmlbuilder-js.git')
.end({ pretty: true});
console.log(xml);
```
will result in:
``` xml
<?xml version="1.0"?>
<root>
<xmlbuilder>
<repo type="git">git://github.com/oozcitak/xmlbuilder-js.git</repo>
</xmlbuilder>
</root>
```
It is also possible to convert objects into nodes:
``` js
builder.create({
root: {
xmlbuilder: {
repo: {
'@type': 'git', // attributes start with @
'#text': 'git://github.com/oozcitak/xmlbuilder-js.git' // text node
}
}
}
});
```
If you need to do some processing:
``` js
var root = builder.create('squares');
root.com('f(x) = x^2');
for(var i = 1; i <= 5; i++)
{
var item = root.ele('data');
item.att('x', i);
item.att('y', i * i);
}
```
This will result in:
``` xml
<?xml version="1.0"?>
<squares>
<!-- f(x) = x^2 -->
<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>
```
See the [wiki](https://github.com/oozcitak/xmlbuilder-js/wiki) for details and [examples](https://github.com/oozcitak/xmlbuilder-js/wiki/Examples) for more complex examples.
// Generated by CoffeeScript 1.12.7
(function() {
var assign, isArray, isEmpty, isFunction, isObject, isPlainObject,
slice = [].slice,
hasProp = {}.hasOwnProperty;
assign = function() {
var i, key, len, source, sources, target;
target = arguments[0], sources = 2 <= arguments.length ? slice.call(arguments, 1) : [];
if (isFunction(Object.assign)) {
Object.assign.apply(null, arguments);
} else {
for (i = 0, len = sources.length; i < len; i++) {
source = sources[i];
if (source != null) {
for (key in source) {
if (!hasProp.call(source, key)) continue;
target[key] = source[key];
}
}
}
}
return target;
};
isFunction = function(val) {
return !!val && Object.prototype.toString.call(val) === '[object Function]';
};
isObject = function(val) {
var ref;
return !!val && ((ref = typeof val) === 'function' || ref === 'object');
};
isArray = function(val) {
if (isFunction(Array.isArray)) {
return Array.isArray(val);
} else {
return Object.prototype.toString.call(val) === '[object Array]';
}
};
isEmpty = function(val) {
var key;
if (isArray(val)) {
return !val.length;
} else {
for (key in val) {
if (!hasProp.call(val, key)) continue;
return false;
}
return true;
}
};
isPlainObject = function(val) {
var ctor, proto;
return isObject(val) && (proto = Object.getPrototypeOf(val)) && (ctor = proto.constructor) && (typeof ctor === 'function') && (ctor instanceof ctor) && (Function.prototype.toString.call(ctor) === Function.prototype.toString.call(Object));
};
module.exports.assign = assign;
module.exports.isFunction = isFunction;
module.exports.isObject = isObject;
module.exports.isArray = isArray;
module.exports.isEmpty = isEmpty;
module.exports.isPlainObject = isPlainObject;
}).call(this);
// Generated by CoffeeScript 1.12.7
(function() {
var XMLAttribute;
module.exports = XMLAttribute = (function() {
function XMLAttribute(parent, name, value) {
this.options = parent.options;
this.stringify = parent.stringify;
if (name == null) {
throw new Error("Missing attribute name of element " + parent.name);
}
if (value == null) {
throw new Error("Missing attribute value for attribute " + name + " of element " + parent.name);
}
this.name = this.stringify.attName(name);
this.value = this.stringify.attValue(value);
}
XMLAttribute.prototype.clone = function() {
return Object.create(this);
};
XMLAttribute.prototype.toString = function(options) {
return this.options.writer.set(options).attribute(this);
};
return XMLAttribute;
})();
}).call(this);
// Generated by CoffeeScript 1.12.7
(function() {
var XMLCData, XMLNode,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
XMLNode = require('./XMLNode');
module.exports = XMLCData = (function(superClass) {
extend(XMLCData, superClass);
function XMLCData(parent, text) {
XMLCData.__super__.constructor.call(this, parent);
if (text == null) {
throw new Error("Missing CDATA text");
}
this.text = this.stringify.cdata(text);
}
XMLCData.prototype.clone = function() {
return Object.create(this);
};
XMLCData.prototype.toString = function(options) {
return this.options.writer.set(options).cdata(this);
};
return XMLCData;
})(XMLNode);
}).call(this);
// Generated by CoffeeScript 1.12.7
(function() {
var XMLComment, XMLNode,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
XMLNode = require('./XMLNode');
module.exports = XMLComment = (function(superClass) {
extend(XMLComment, superClass);
function XMLComment(parent, text) {
XMLComment.__super__.constructor.call(this, parent);
if (text == null) {
throw new Error("Missing comment text");
}
this.text = this.stringify.comment(text);
}
XMLComment.prototype.clone = function() {
return Object.create(this);
};
XMLComment.prototype.toString = function(options) {
return this.options.writer.set(options).comment(this);
};
return XMLComment;
})(XMLNode);
}).call(this);
// Generated by CoffeeScript 1.12.7
(function() {
var XMLDTDAttList, XMLNode,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
XMLNode = require('./XMLNode');
module.exports = XMLDTDAttList = (function(superClass) {
extend(XMLDTDAttList, superClass);
function XMLDTDAttList(parent, elementName, attributeName, attributeType, defaultValueType, defaultValue) {
XMLDTDAttList.__super__.constructor.call(this, parent);
if (elementName == null) {
throw new Error("Missing DTD element name");
}
if (attributeName == null) {
throw new Error("Missing DTD attribute name");
}
if (!attributeType) {
throw new Error("Missing DTD attribute type");
}
if (!defaultValueType) {
throw new Error("Missing DTD attribute default");
}
if (defaultValueType.indexOf('#') !== 0) {
defaultValueType = '#' + defaultValueType;
}
if (!defaultValueType.match(/^(#REQUIRED|#IMPLIED|#FIXED|#DEFAULT)$/)) {
throw new Error("Invalid default value type; expected: #REQUIRED, #IMPLIED, #FIXED or #DEFAULT");
}
if (defaultValue && !defaultValueType.match(/^(#FIXED|#DEFAULT)$/)) {
throw new Error("Default value only applies to #FIXED or #DEFAULT");
}
this.elementName = this.stringify.eleName(elementName);
this.attributeName = this.stringify.attName(attributeName);
this.attributeType = this.stringify.dtdAttType(attributeType);
this.defaultValue = this.stringify.dtdAttDefault(defaultValue);
this.defaultValueType = defaultValueType;
}
XMLDTDAttList.prototype.toString = function(options) {
return this.options.writer.set(options).dtdAttList(this);
};
return XMLDTDAttList;
})(XMLNode);
}).call(this);
// Generated by CoffeeScript 1.12.7
(function() {
var XMLDTDElement, XMLNode,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
XMLNode = require('./XMLNode');
module.exports = XMLDTDElement = (function(superClass) {
extend(XMLDTDElement, superClass);
function XMLDTDElement(parent, name, value) {
XMLDTDElement.__super__.constructor.call(this, parent);
if (name == null) {
throw new Error("Missing DTD element name");
}
if (!value) {
value = '(#PCDATA)';
}
if (Array.isArray(value)) {
value = '(' + value.join(',') + ')';
}
this.name = this.stringify.eleName(name);
this.value = this.stringify.dtdElementValue(value);
}
XMLDTDElement.prototype.toString = function(options) {
return this.options.writer.set(options).dtdElement(this);
};
return XMLDTDElement;
})(XMLNode);
}).call(this);
// Generated by CoffeeScript 1.12.7
(function() {
var XMLDTDEntity, XMLNode, isObject,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
isObject = require('./Utility').isObject;
XMLNode = require('./XMLNode');
module.exports = XMLDTDEntity = (function(superClass) {
extend(XMLDTDEntity, superClass);
function XMLDTDEntity(parent, pe, name, value) {
XMLDTDEntity.__super__.constructor.call(this, parent);
if (name == null) {
throw new Error("Missing entity name");
}
if (value == null) {
throw new Error("Missing entity value");
}
this.pe = !!pe;
this.name = this.stringify.eleName(name);
if (!isObject(value)) {
this.value = this.stringify.dtdEntityValue(value);
} else {
if (!value.pubID && !value.sysID) {
throw new Error("Public and/or system identifiers are required for an external entity");
}
if (value.pubID && !value.sysID) {
throw new Error("System identifier is required for a public external entity");
}
if (value.pubID != null) {
this.pubID = this.stringify.dtdPubID(value.pubID);
}
if (value.sysID != null) {
this.sysID = this.stringify.dtdSysID(value.sysID);
}
if (value.nData != null) {
this.nData = this.stringify.dtdNData(value.nData);
}
if (this.pe && this.nData) {
throw new Error("Notation declaration is not allowed in a parameter entity");
}
}
}
XMLDTDEntity.prototype.toString = function(options) {
return this.options.writer.set(options).dtdEntity(this);
};
return XMLDTDEntity;
})(XMLNode);
}).call(this);
// Generated by CoffeeScript 1.12.7
(function() {
var XMLDTDNotation, XMLNode,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
XMLNode = require('./XMLNode');
module.exports = XMLDTDNotation = (function(superClass) {
extend(XMLDTDNotation, superClass);
function XMLDTDNotation(parent, name, value) {
XMLDTDNotation.__super__.constructor.call(this, parent);
if (name == null) {
throw new Error("Missing notation name");
}
if (!value.pubID && !value.sysID) {
throw new Error("Public or system identifiers are required for an external entity");
}
this.name = this.stringify.eleName(name);
if (value.pubID != null) {
this.pubID = this.stringify.dtdPubID(value.pubID);
}
if (value.sysID != null) {
this.sysID = this.stringify.dtdSysID(value.sysID);
}
}
XMLDTDNotation.prototype.toString = function(options) {
return this.options.writer.set(options).dtdNotation(this);
};
return XMLDTDNotation;
})(XMLNode);
}).call(this);
// Generated by CoffeeScript 1.12.7
(function() {
var XMLDeclaration, XMLNode, isObject,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
isObject = require('./Utility').isObject;
XMLNode = require('./XMLNode');
module.exports = XMLDeclaration = (function(superClass) {
extend(XMLDeclaration, superClass);
function XMLDeclaration(parent, version, encoding, standalone) {
var ref;
XMLDeclaration.__super__.constructor.call(this, parent);
if (isObject(version)) {
ref = version, version = ref.version, encoding = ref.encoding, standalone = ref.standalone;
}
if (!version) {
version = '1.0';
}
this.version = this.stringify.xmlVersion(version);
if (encoding != null) {
this.encoding = this.stringify.xmlEncoding(encoding);
}
if (standalone != null) {
this.standalone = this.stringify.xmlStandalone(standalone);
}
}
XMLDeclaration.prototype.toString = function(options) {
return this.options.writer.set(options).declaration(this);
};
return XMLDeclaration;
})(XMLNode);
}).call(this);
// Generated by CoffeeScript 1.12.7
(function() {
var XMLDTDAttList, XMLDTDElement, XMLDTDEntity, XMLDTDNotation, XMLDocType, XMLNode, isObject,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
isObject = require('./Utility').isObject;
XMLNode = require('./XMLNode');
XMLDTDAttList = require('./XMLDTDAttList');
XMLDTDEntity = require('./XMLDTDEntity');
XMLDTDElement = require('./XMLDTDElement');
XMLDTDNotation = require('./XMLDTDNotation');
module.exports = XMLDocType = (function(superClass) {
extend(XMLDocType, superClass);
function XMLDocType(parent, pubID, sysID) {
var ref, ref1;
XMLDocType.__super__.constructor.call(this, parent);
this.documentObject = parent;
if (isObject(pubID)) {
ref = pubID, pubID = ref.pubID, sysID = ref.sysID;
}
if (sysID == null) {
ref1 = [pubID, sysID], sysID = ref1[0], pubID = ref1[1];
}
if (pubID != null) {
this.pubID = this.stringify.dtdPubID(pubID);
}
if (sysID != null) {
this.sysID = this.stringify.dtdSysID(sysID);
}
}
XMLDocType.prototype.element = function(name, value) {
var child;
child = new XMLDTDElement(this, name, value);
this.children.push(child);
return this;
};
XMLDocType.prototype.attList = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) {
var child;
child = new XMLDTDAttList(this, elementName, attributeName, attributeType, defaultValueType, defaultValue);
this.children.push(child);
return this;
};
XMLDocType.prototype.entity = function(name, value) {
var child;
child = new XMLDTDEntity(this, false, name, value);
this.children.push(child);
return this;
};
XMLDocType.prototype.pEntity = function(name, value) {
var child;
child = new XMLDTDEntity(this, true, name, value);
this.children.push(child);
return this;
};
XMLDocType.prototype.notation = function(name, value) {
var child;
child = new XMLDTDNotation(this, name, value);
this.children.push(child);
return this;
};
XMLDocType.prototype.toString = function(options) {
return this.options.writer.set(options).docType(this);
};
XMLDocType.prototype.ele = function(name, value) {
return this.element(name, value);
};
XMLDocType.prototype.att = function(elementName, attributeName, attributeType, defaultValueType, defaultValue) {
return this.attList(elementName, attributeName, attributeType, defaultValueType, defaultValue);
};
XMLDocType.prototype.ent = function(name, value) {
return this.entity(name, value);
};
XMLDocType.prototype.pent = function(name, value) {
return this.pEntity(name, value);
};
XMLDocType.prototype.not = function(name, value) {
return this.notation(name, value);
};
XMLDocType.prototype.up = function() {
return this.root() || this.documentObject;
};
return XMLDocType;
})(XMLNode);
}).call(this);
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.