diff --git a/src/framework/XMLAttr.cpp b/src/framework/XMLAttr.cpp
index eab7b0122ae9aca96c4c3fa3245f7b8bf784ca28..baeb5b6e853c4b2e5c86b3266801a6a2b67f2b59 100644
--- a/src/framework/XMLAttr.cpp
+++ b/src/framework/XMLAttr.cpp
@@ -56,6 +56,10 @@
 
 /**
  * $Log$
+ * Revision 1.6  2000/04/10 22:42:52  roddey
+ * Extended the buffer reuse to the QName field, to further increase
+ * performance of attribute heavy applications.
+ *
  * Revision 1.5  2000/03/28 19:43:16  roddey
  * Fixes for signed/unsigned warnings. New work for two way transcoding
  * stuff.
@@ -99,6 +103,7 @@ XMLAttr::XMLAttr() :
     , fPrefix(0)
     , fPrefixBufSz(0)
     , fQName(0)
+    , fQNameBufSz(0)
     , fType(XMLAttDef::CData)
     , fValue(0)
     , fValueBufSz(0)
@@ -119,6 +124,7 @@ XMLAttr::XMLAttr(   const   unsigned int        uriId
     , fPrefix(0)
     , fPrefixBufSz(0)
     , fQName(0)
+    , fQNameBufSz(0)
     , fType(type)
     , fValue(0)
     , fValueBufSz(0)
@@ -147,30 +153,50 @@ XMLAttr::XMLAttr(   const   unsigned int        uriId
 // ---------------------------------------------------------------------------
 const XMLCh* XMLAttr::getQName() const
 {
-    // Fault in the QName if not already done
-    if (!fQName)
+    //
+    //  If there is no buffer, or if there is but we've not faulted in the
+    //  value yet, then we have to do that now.
+    //
+    if (!fQName || !*fQName)
     {
+        //
+        //  Calculate the worst case size buffer we will need. We use the
+        //  current high water marks of the prefix and name buffers, so it
+        //  might be a little wasteful of memory but we don't have to do
+        //  string len operations on the two strings.
+        //
+        const unsigned int neededLen = fPrefixBufSz + fNameBufSz + 1;
+
+        //
+        //  If no buffer, or the current one is too small, then allocate one
+        //  and get rid of any old one.
+        //
+        if (!fQName || (neededLen > fQNameBufSz))
+        {
+            delete [] fQName;
+
+            // We have to cast off the const'ness to do this
+            ((XMLAttr*)this)->fQNameBufSz = neededLen;
+            ((XMLAttr*)this)->fQName = new XMLCh[neededLen + 1];
+
+            // Make sure its initially empty
+            *fQName = 0;
+        }
+
+        //
+        //  If we have a prefix, then do the prefix:name version. Else, its
+        //  just the name.
+        //
         if (*fPrefix)
         {
-            //
-            //  Calc the length. we just use the current buffer sizes
-            //  of thename and prefix, so this is a worst case length
-            //  and its faster than doing string len calls to figure
-            //  out the exact length.
-            //
-            const unsigned int len = fPrefixBufSz + fNameBufSz + 1;
             const XMLCh colonStr[] = { chColon, chNull };
-
-            // We are faulting this guy in, so cast of const'ness
-            ((XMLAttr*)this)->fQName = new XMLCh[len + 1];
             XMLString::copyString(fQName, fPrefix);
             XMLString::catString(fQName, colonStr);
             XMLString::catString(fQName, fName);
         }
          else
         {
-            // We are faulting this guy in, so cast of const'ness
-            ((XMLAttr*)this)->fQName = XMLString::replicate(fName);
+            XMLString::copyString(fQName, fName);
         }
     }
     return fQName;
@@ -204,9 +230,9 @@ void XMLAttr::setName(  const   unsigned int    uriId
     }
     XMLString::moveChars(fPrefix, attrPrefix, newLen + 1);
 
-    // And clean up the QName and leave it undone until/if asked for again
-    delete [] fQName;
-    fQName = 0;
+    // And clean up any QName and leave it undone until/if asked for again
+    if (fQName)
+        *fQName = 0;
 
     // And finally store the URI id parameter
     fURIId = uriId;
diff --git a/src/framework/XMLAttr.hpp b/src/framework/XMLAttr.hpp
index e1ac623b60457d0a8f8edd98d3a511e66dd427f6..462ff56b17b67d95d2e6fa67739ffc9e86acf79b 100644
--- a/src/framework/XMLAttr.hpp
+++ b/src/framework/XMLAttr.hpp
@@ -56,6 +56,10 @@
 
 /*
  * $Log$
+ * Revision 1.6  2000/04/10 22:42:53  roddey
+ * Extended the buffer reuse to the QName field, to further increase
+ * performance of attribute heavy applications.
+ *
  * Revision 1.5  2000/03/02 19:54:24  roddey
  * This checkin includes many changes done while waiting for the
  * 1.1.0 code to be finished. I can't list them all here, but a list is
@@ -347,14 +351,16 @@ private :
     //  fPrefix
     //  fPrefixBufSz
     //      The prefix that was applied to this attribute's name, and the
-    //      current size of the buffer (minus one, where the null is.) It
-    //      really does not matter technically but it might be required
-    //      for pratical reasons, to recreate the original document for
-    //      instance.
+    //      current size of the buffer (minus one for the null.) Prefixes
+    //      really don't matter technically but it might be required for
+    //      pratical reasons, to recreate the original document for instance.
     //
     //  fQName
+    //  fQNameBufSz
     //      This is the QName form of the name, which is faulted in (from the
-    //      prefix and name) upon request.
+    //      prefix and name) upon request. The size field indicates the
+    //      current size of the buffer (minus one for the null.) It will be
+    //      zero until fauled in.
     //
     //  fSpecified
     //      True if this attribute appeared in the element; else, false if
@@ -377,6 +383,7 @@ private :
     XMLCh*              fPrefix;
     unsigned int        fPrefixBufSz;
     XMLCh*              fQName;
+    unsigned int        fQNameBufSz;
     bool                fSpecified;
     XMLAttDef::AttTypes fType;
     XMLCh*              fValue;