Namespaces are used to qualify your element names, prefixes are used to simplify you XML. By default, there is an namespace with an "empty" uri.
Expanding Tomalaks example:
<!-- Mixing namespaces default namespace -->
<node xmlns:gc="http://other/namespace/gc"> <!-- node is in default NS -->
<child> <!-- child is still in default NS, inherited from parent - node -->
<gc:grandchild/> <!-- grandchild is in the "http://other/namespace/gc", because of gc prefix -->
</child>
<child xmlns="http://some/namespace/uri/" xmlns:gc2="http://other/namespace/gc"> <!-- node is in "http://home/namespace/uri" because of declration -->
<gc2:grandchild/> <!-- again, in "http://other/namespace/gc", despite different prefix -->
<grandchild/> <!-- yet this one is in "http://home/namespace/uri", no prefix, inherited from parent -->
</child>
</node>
The take away here is that both "child" node are DIFFERENT NODES. They look the same, but their "fully qualified names" are different". This is particularly important in XSL.
Same with the grandchildren. gc:grandchild and gc2:grandchild are THE SAME, they share the same Namespace URI, but use different prefixes. The third grandchild node is different, as it's using its inherited namespace from the parent child node.
Namespaces are important because they let you "mix and match" xml in a single document from different vocabularies. For example embedding SVG markup within an XHTML document. Using namespaces prevents having overlap of the same base node names.
For most simple XML problems, they are unnecessary. But when you start merging standards, etc. they become very important.
Another example is embedding SAML assertions within SOAP envelopes for web services. SOAP is one standard, SAML is another -- independent standards and standard bodies, but both allow areas of "arbitrary XML" to be inserted in their documents. Namespaces keep the content separate.