Skip to content

Commit

Permalink
added: output xml with $.xml() [@Maciek416]
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewmueller committed Jun 9, 2013
2 parents 9ec0c37 + 74a2514 commit f6d4ea5
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 5 deletions.
16 changes: 15 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ $('ul').text()
```

### Rendering
When you're ready to render the document, you can use `html` utility function:
When you're ready to render the document, you can use the `html` utility function:

```js
$.html()
Expand All @@ -523,6 +523,20 @@ $.html('.pear')
//=> <li class="pear">Pear</li>
```

By default, `html` will leave some tags open. Sometimes you may instead want to render a valid XML document. For example, you might parse the following XML snippet:

```xml
$ = cheerio.load('<media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/>');
```

... and later want to render to XML. To do this, you can use the 'xml' utility function:

```js
$.xml()
//=> <media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/>
```


### Miscellaneous
DOM element methods that don't fit anywhere else

Expand Down
19 changes: 15 additions & 4 deletions lib/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ var render = module.exports = function(dom, opts) {
var pushVal;

if (tagType[elem.type])
pushVal = renderTag(elem);
pushVal = renderTag(elem, xmlMode);
else if (elem.type === 'directive')
pushVal = renderDirective(elem);
else if (elem.type === 'comment')
Expand All @@ -89,19 +89,30 @@ var render = module.exports = function(dom, opts) {
if (elem.children)
output.push(render(elem.children, opts));

if ((!singleTag[elem.name] || xmlMode) && tagType[elem.type])
output.push('</' + elem.name + '>');
if ((!singleTag[elem.name] || xmlMode) && tagType[elem.type]) {
if (!isClosedTag(elem, xmlMode)) {
output.push('</' + elem.name + '>');
}
}
});

return output.join('');
};

var renderTag = function(elem) {
var isClosedTag = function(elem, xmlMode){
return (xmlMode && (!elem.children || elem.children.length === 0));
}

var renderTag = function(elem, xmlMode) {
var tag = '<' + elem.name;

if (elem.attribs && _.size(elem.attribs)) {
tag += ' ' + formatAttrs(elem.attribs);
}

if (isClosedTag(elem, xmlMode)) {
tag += '/';
}

return tag + '>';
};
Expand Down
15 changes: 15 additions & 0 deletions lib/static.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ var html = exports.html = function(dom) {
}
};

/**
* $.xml([selector | dom])
*/

var xml = exports.xml = function(dom) {
if (dom) {
dom = (typeof dom === 'string') ? select(dom, this._root) : dom;
return render(dom, { xmlMode: true });
} else if (this._root && this._root.children) {
return render(this._root.children, { xmlMode: true });
} else {
return '';
}
};

/**
* $.text(dom)
*/
Expand Down
29 changes: 29 additions & 0 deletions test/xml.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var expect = require('expect.js'),
_ = require('underscore'),
cheerio = require('../lib/cheerio');

var xml = function(str, options) {
options = _.extend({ xmlMode: true }, options);
var dom = cheerio.load(str, options);
return dom.xml();
};

describe('render', function() {

describe('(xml)', function() {

it('should render <media:thumbnail /> tags correctly', function(done) {
var str = '<media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123" />';
expect(xml(str)).to.equal('<media:thumbnail url="http://www.foo.com/keyframe.jpg" width="75" height="50" time="12:05:01.123"/>');
done();
});

it('should render <link /> tags (RSS) correctly', function(done) {
var str = '<link>http://www.github.com/</link>';
expect(xml(str)).to.equal('<link>http://www.github.com/</link>');
done();
});

});

});

0 comments on commit f6d4ea5

Please sign in to comment.