Get all text nodes?

J

Jeremy

I have a script that runs a regular expression replace on all text in
the document. Currently, I recurse the entire document looking for text
nodes and run the replacement on the text nodes when I find them. The
problem is, this gets really slow for complicated documents.

Is there a better way to either:
a) Get a flat list of all the text nodes in the document (like
getElementsByTagName, only for text nodes)
b) Run a regex replace on only text in the document (not tags or their
attributes)?

Thanks,
Jeremy
 
M

Martin Honnen

Jeremy said:
Is there a better way to either:
a) Get a flat list of all the text nodes in the document (like
getElementsByTagName, only for text nodes)

Mozilla and the new Opera 9 provide XPath over HTML so there you could
do e.g.

var xPathResult = document.evaluate(
'.//text()[normalize-space(.) != ""]',
document.body,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
for (var i = 0, l = xPathResult.snapshotLength; i < l; i++) {
var textNode = xPathResult.snapshotItem(i);
textNode.data = textNode.data.replace(/somePattern/g, 'replacement');
}

to iterate over all text nodes (well I have choosen the XPath to ignore
white space text nodes).

I haven't checked whether that has any performance gains.

Opera 8 and 9 also implement the W3C DOM Level 2 NodeIterator interface
so you could also use that to iterate over all text nodes e.g. here is
an example that use a node filter with a regular expression check so
that the iterator simply has to manipulate the nodes found:

var nodeIterator = document.createNodeIterator(
document.body,
NodeFilter.SHOW_TEXT,
{ acceptNode : function (node) {
return /somePattern/.test(node.data) ? NodeFilter.FILTER_ACCEPT :
NodeFilter.FILTER_REJECT;
}},
true
);

var textNode;

while ((textNode = nodeIterator.nextNode()) != null) {
textNode.data = textNode.data.replace(/somePattern/g, 'replacement');
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top