431 Stimmen

Eine HTML-Zeichenkette mit JS parsen

Ich möchte eine Zeichenkette parsen, die HTML-Text enthält. Ich möchte dies in JavaScript tun.

Ich habe die Reine JavaScript-HTML-Parser-Bibliothek aber es scheint, dass es den HTML-Code meiner aktuellen Seite analysiert, nicht von einer Zeichenfolge. Denn wenn ich den nachstehenden Code ausprobiere, ändert er den Titel meiner Seite:

var parser = new HTMLtoDOM("<html><head><title>titleTest</title></head><body><a href='test0'>test01</a><a href='test1'>test02</a><a href='test2'>test03</a></body></html>", document);

Mein Ziel ist es, Links aus einer externen HTML-Seite zu extrahieren, die ich wie einen String lese.

Kennen Sie eine API, die dies ermöglicht?

512voto

Florian Margaine Punkte 54172

Erstellen Sie ein Dummy-DOM-Element und fügen Sie ihm die Zeichenfolge hinzu. Dann können Sie es wie jedes andere DOM-Element manipulieren.

var el = document.createElement( 'html' );
el.innerHTML = "<html><head><title>titleTest</title></head><body><a href='test0'>test01</a><a href='test1'>test02</a><a href='test2'>test03</a></body></html>";

el.getElementsByTagName( 'a' ); // Live NodeList of your anchor elements

Bearbeiten: Eine jQuery-Antwort hinzugefügt, um die Fans zu erfreuen!

var el = $( '<div></div>' );
el.html("<html><head><title>titleTest</title></head><body><a href='test0'>test01</a><a href='test1'>test02</a><a href='test2'>test03</a></body></html>");

$('a', el) // All the anchor elements

437voto

Cilan Punkte 11743

Es ist ganz einfach:

const parser = new DOMParser();
const htmlDoc = parser.parseFromString(txt, 'text/html');
// do whatever you want with htmlDoc.getElementsByTagName('a');

Laut MDN Um dies in Chrome zu tun, müssen Sie XML wie folgt parsen:

const parser = new DOMParser();
const htmlDoc = parser.parseFromString(txt, 'text/xml');
// do whatever you want with htmlDoc.getElementsByTagName('a');

Es wird derzeit nicht von Webkit unterstützt und man müsste Florians Antwort folgen, und es ist unbekannt, dass es in den meisten Fällen auf mobilen Browsern funktioniert.

Edit: Jetzt weitgehend unterstützt

45voto

Munawwar Punkte 1594

EDIT: Die folgende Lösung gilt nur für HTML-"Fragmente", da html, head und body entfernt werden. Ich denke, die Lösung für diese Frage ist die Methode parseFromString() von DOMParser:

const parser = new DOMParser();
const document = parser.parseFromString(html, "text/html");

Bei HTML-Fragmenten funktionieren die hier aufgeführten Lösungen für die meisten HTML-Fragmente, aber in bestimmten Fällen funktionieren sie nicht.

Versuchen Sie zum Beispiel Folgendes zu analysieren <td>Test</td> . Dieser funktioniert weder bei der Lösung div.innerHTML noch bei der Lösung DOMParser.prototype.parseFromString oder range.createContextualFragment. Das td-Tag geht verloren und nur der Text bleibt.

Nur jQuery beherrscht diesen Fall gut.

Die künftige Lösung (MS Edge 13+) besteht also in der Verwendung von Vorlagen-Tags:

function parseHTML(html) {
    var t = document.createElement('template');
    t.innerHTML = html;
    return t.content;
}

var documentFragment = parseHTML('<td>Test</td>');

Für ältere Browser habe ich die parseHTML()-Methode von jQuery in einen eigenen Gist extrahiert - https://gist.github.com/Munawwar/6e6362dbdf77c7865a99

31voto

Mathieu Punkte 5204
var doc = new DOMParser().parseFromString(html, "text/html");
var links = doc.querySelectorAll("a");

8voto

AnthumChris Punkte 6798
const parse = Range.prototype.createContextualFragment.bind(document.createRange());

document.body.appendChild( parse('<p><strong>Today is:</strong></p>') ),
document.body.appendChild( parse(`<p style="background: #eee">${new Date()}</p>`) );

Nur gültiges Kind Node s innerhalb der übergeordneten Node (Beginn der Range ) geparst werden. Andernfalls kann es zu unerwarteten Ergebnissen kommen:

// <body> is "parent" Node, start of Range
const parseRange = document.createRange();
const parse = Range.prototype.createContextualFragment.bind(parseRange);

// Returns Text "1 2" because td, tr, tbody are not valid children of <body>
parse('<td>1</td> <td>2</td>');
parse('<tr><td>1</td> <td>2</td></tr>');
parse('<tbody><tr><td>1</td> <td>2</td></tr></tbody>');

// Returns <table>, which is a valid child of <body>
parse('<table> <td>1</td> <td>2</td> </table>');
parse('<table> <tr> <td>1</td> <td>2</td> </tr> </table>');
parse('<table> <tbody> <td>1</td> <td>2</td> </tbody> </table>');

// <tr> is parent Node, start of Range
parseRange.setStart(document.createElement('tr'), 0);

// Returns [<td>, <td>] element array
parse('<td>1</td> <td>2</td>');
parse('<tr> <td>1</td> <td>2</td> </tr>');
parse('<tbody> <td>1</td> <td>2</td> </tbody>');
parse('<table> <td>1</td> <td>2</td> </table>');

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X