Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle '<' and '>' characters in attribute values #2

Open
vpulim opened this issue Jun 25, 2010 · 8 comments
Open

handle '<' and '>' characters in attribute values #2

vpulim opened this issue Jun 25, 2010 · 8 comments

Comments

@vpulim
Copy link

vpulim commented Jun 25, 2010

i have html that looks like the following:

<span title="first line<br>second line"></span>

it would be great if the 'br' is actually treated as part of the attribute value of 'title' instead of being treated as a new tag element

@tautologistics
Copy link
Owner

The way parsing is done right now, that isn't easily possible. The example isn't valid HTML because the "<" and ">" should be escaped. I'm working on a 2.0 that should handle your example via the setting of an option.

@vpulim
Copy link
Author

vpulim commented Jul 1, 2010

i know its not valid HTML but unfortunately there is HTML out in the wild that doesn't escape brackets properly and most browsers do seem to ignore brackets when they are part of an attribute value. but thanks for attempting to handle it properly in version 2.0. your parser is extremely fast and useful even in its current state. great work!

@tluyben
Copy link

tluyben commented Feb 27, 2012

When will this be fixed? A lot of sites have this issue...

@tluyben
Copy link

tluyben commented Feb 28, 2012

I really needed a solution asap, so here we go with this small hack which works for all my cases; in the htmlparser.js just find the parseTags and add this bit of code;

Parser.prototype.parseTags = function Parser$parseTags () {
    var bufferEnd = this._buffer.length - 1;

    while (Parser._reTags.test(this._buffer)) {

        this._next = Parser._reTags.lastIndex - 1;
        var tagSep;// = this._buffer.charAt(this._next); //The currently found tag marker
        var rawData;// = this._buffer.substring(this._current, this._next); //The next chunk of data to parse

        var a1 = 0, a2 = 0; 
        for (var i=this._current; i<this._buffer.length; i++) {
            if (this._buffer.charAt(i) == '"') {
                if (a2 == 0) {
                    if (a1 == 0) a1 = i; else a1 = 0;
                }
            }
            if (this._buffer.charAt(i) == "'") {
                if (a1 == 0) {
                    if (a2 == 0) a2 = i; else a2 = 0;
                }
            }
            if (a1 == 0 && a2 == 0 && (this._buffer.charAt(i) == '>' || this._buffer.charAt(i) == '<')) {
                this._next = i; 
                tagSep = this._buffer.charAt(this._next);
                rawData = this._buffer.substring(this._current, this._next); 
                break;
            }
        }

After adding this my jquery experiments are the same as they are in Firebug which saves me tons of work.

@vpulim
Copy link
Author

vpulim commented Feb 28, 2012

@tluyben: this seems to work well with my test cases as well. thanks for the patch!

@tluyben
Copy link

tluyben commented Feb 28, 2012

Ofcourse you can remove the regex call altogether to save some speed;

    //while (Parser._reTags.test(this._buffer)) {
    while (true) {
        this._next = -1; //Parser._reTags.lastIndex - 1;
        var tagSep;// = this._buffer.charAt(this._next); //The currently found tag marker
        var rawData;// = this._buffer.substring(this._current, this._next); //The next chunk of data to parse

        var a1 = 0, a2 = 0; 
        for (var i=this._current; i<this._buffer.length; i++) {
            if (this._buffer.charAt(i) == '"') {
                if (a2 == 0) {
                    if (a1 == 0) a1 = i; else a1 = 0;
                }
            }
            if (this._buffer.charAt(i) == "'") {
                if (a1 == 0) {
                    if (a2 == 0) a2 = i; else a2 = 0;
                }
            }
            if (a1 == 0 && a2 == 0 && (this._buffer.charAt(i) == '>' || this._buffer.charAt(i) == '<')) {
                this._next = i; 
                tagSep = this._buffer.charAt(this._next);
                rawData = this._buffer.substring(this._current, this._next); 
                break;
            }
        }

        // are we done? 
        if (this._next < 0) {
            break;
        }

And you need a1,a2 only as 0/1 (boolean); not as the index; it's an index because while typing this I was going to follow another strategy which was harder which did use those indexes.

@scriby
Copy link

scriby commented Jun 19, 2012

Any chance on getting this fix in? It would be a great help for a project I'm working on.

@petrbela
Copy link

@scriby You can use my patched version (simply change dependency from 1.x to git://github.com/petrbela/node-htmlparser.git)... however, I think you'll be better off with v2.

kirbysayshi pushed a commit to kirbysayshi/node-htmlparser that referenced this issue Dec 19, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants