testere
testere

Reputation: 91

Replace string - How to replace each word once

I have an xml dictionary as shown below.

<word definition="The primary income-earner in a household">bread winner</word>
<word definition="One who wins, or gains by success in competition, contest, or gaming">winner</word>

Whenerver there is a word from dictionary in my html, that word will be replaced with link and definition as title. When link is hovered, user should see the definition.

var allwords = xmlDoc.getElementsByTagName("word");
for (var i=0; i<allwords.length; i++)
    {
            var name = allwords[i].lastChild.nodeValue;

            var linked = '<a href ="#" title="' +  allwords[i].lastChild.nodeValue + ': ' + allwords[i].getAttribute("definition") + '">' + allwords[i].lastChild.nodeValue + '</a>'; 
    }

Here is my replacer

function replacer(oldstring, newstring) {
document.body.innerHTML = document.body.innerHTML.replace(oldstring, newstring);
}

But problem is once bread winner changes to linked form, also winner changes since bread winner includes winner, winner changes twice, and all the code mixes up.

I am asking if there is a way, once bread winner changes winner should not change anymore.

Thanks in advance!

Upvotes: 3

Views: 302

Answers (4)

Anthony Faull
Anthony Faull

Reputation: 17957

You'll need to iterate through the matching text nodes, and only replace those that don't have an A tag as an ancestor in the DOM.

Upvotes: 0

kinakuta
kinakuta

Reputation: 9037

You need some kind of sentry to prevent processing a term that's already been processed. I'd recommend wrapping the replaced terms with another element (not clear on how your html is structured, so I'm not sure what would work here, but a span would be the simplest way in normal html). Then your logic would just skip replacing words that had a parent element of whatever you decided to wrap it with.

Upvotes: 0

Gedrox
Gedrox

Reputation: 3612

Try function strtr($text, $fromList, $toList). It should replace each term once.

Upvotes: -1

Jon
Jon

Reputation: 437326

What about something like this:

for (var i=0; i<allwords.length; i++)
{
    if(allwords[i].firstChild.name == 'a') {
        // This word has been linked already, skip it
    }

    // your code
}

Upvotes: 2

Related Questions