diff --git a/src/xercesc/internal/IGXMLScanner.cpp b/src/xercesc/internal/IGXMLScanner.cpp
index e34b3460f5d5a0145864b60710b35ad6be18fcac..1cb992cf2748a3974618ada66fca208c4cb68115 100644
--- a/src/xercesc/internal/IGXMLScanner.cpp
+++ b/src/xercesc/internal/IGXMLScanner.cpp
@@ -1025,7 +1025,7 @@ void IGXMLScanner::scanEndTag(bool& gotData)
                 for (int i = oldCount - 1; i >= 0; i--) {
 
                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(i);
-                    matcher->endElement(*(topElem->fThisElement));
+                    matcher->endElement(*(topElem->fThisElement), fContent.getRawBuffer());
                 }
 
                 if (fMatcherStack->size() > 0) {
@@ -1040,14 +1040,8 @@ void IGXMLScanner::scanEndTag(bool& gotData)
                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
                     IdentityConstraint* ic = matcher->getIdentityConstraint();
 
-                    if (ic  && (ic->getType() != IdentityConstraint::KEYREF)) {
-
-                        matcher->endDocumentFragment();
+                    if (ic  && (ic->getType() != IdentityConstraint::KEYREF))
                         fValueStoreCache->transplant(ic, matcher->getInitialDepth());
-                    }
-                    else if (!ic) {
-                        matcher->endDocumentFragment();
-                    }
                 }
 
                 // now handle keyref's...
@@ -1063,8 +1057,6 @@ void IGXMLScanner::scanEndTag(bool& gotData)
                         if (values) { // nothing to do if nothing matched!
                             values->endDcocumentFragment(fValueStoreCache);
                         }
-
-                        matcher->endDocumentFragment();
                     }
                 }
 
@@ -1928,6 +1920,9 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
     //  ever be false if this is the root and its empty.
     gotData = true;
 
+    // Reset element content buffer
+    fContent.reset();
+
     //  The current position is after the open bracket, so we need to read in
     //  in the element name.
     if (!fReaderMgr.getName(fQNameBuf))
@@ -2437,7 +2432,7 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
                     for (int i = oldCount - 1; i >= 0; i--) {
 
                         XPathMatcher* matcher = fMatcherStack->getMatcherAt(i);
-                        matcher->endElement(*elemDecl);
+                        matcher->endElement(*elemDecl, fContent.getRawBuffer());
                     }
 
                     if (fMatcherStack->size() > 0) {
@@ -2452,14 +2447,8 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
                         XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
                         IdentityConstraint* ic = matcher->getIdentityConstraint();
 
-                        if (ic  && (ic->getType() != IdentityConstraint::KEYREF)) {
-
-                            matcher->endDocumentFragment();
+                        if (ic  && (ic->getType() != IdentityConstraint::KEYREF))
                             fValueStoreCache->transplant(ic, matcher->getInitialDepth());
-                        }
-                        else if (!ic) {
-                            matcher->endDocumentFragment();
-                        }
                     }
 
                     // now handle keyref's...
@@ -2475,8 +2464,6 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
                             if (values) { // nothing to do if nothing matched!
                                 values->endDcocumentFragment(fValueStoreCache);
                             }
-
-                            matcher->endDocumentFragment();
                         }
                     }
 
diff --git a/src/xercesc/internal/IGXMLScanner.hpp b/src/xercesc/internal/IGXMLScanner.hpp
index 2591ec9b7ceceacabdfe136e598dda0b0ee4873d..8723fbf9e5b19efc87c8c203e94547e648b7e4cf 100644
--- a/src/xercesc/internal/IGXMLScanner.hpp
+++ b/src/xercesc/internal/IGXMLScanner.hpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.2  2003/01/13 16:30:18  knoaman
+ * [Bug 14469] Validator doesn't enforce xsd:key.
+ *
  * Revision 1.1  2002/12/04 02:05:25  knoaman
  * Initial checkin.
  *
@@ -292,6 +295,7 @@ private :
     unsigned int                fElemStateSize;
     unsigned int*               fElemState;
     ElemStack                   fElemStack;
+    XMLBuffer                   fContent;
     RefVectorOf<KVStringPair>*  fRawAttrList;
     DTDValidator*               fDTDValidator;
     SchemaValidator*            fSchemaValidator;
diff --git a/src/xercesc/internal/IGXMLScanner2.cpp b/src/xercesc/internal/IGXMLScanner2.cpp
index 842961fad2b8a11722a958f96b8d88cb8266545f..81a8bf1abf65f3e09131c56186ae0574735bc418 100644
--- a/src/xercesc/internal/IGXMLScanner2.cpp
+++ b/src/xercesc/internal/IGXMLScanner2.cpp
@@ -965,11 +965,8 @@ void IGXMLScanner::sendCharData(XMLBuffer& toSend)
                     ((SchemaValidator*) fValidator)->setDatatypeBuffer(toFill.getRawBuffer());
 
                     // call all active identity constraints
-                    unsigned int count = fMatcherStack->getMatcherCount();
-
-                    for (unsigned int i = 0; i < count; i++) {
-                        fMatcherStack->getMatcherAt(i)->docCharacters(toFill.getRawBuffer(), toFill.getLen());
-                    }
+                    if (fMatcherStack->getMatcherCount())
+                        fContent.append(toFill.getRawBuffer(), toFill.getLen());
 
                     if (fDocHandler)
                         fDocHandler->docCharacters(toFill.getRawBuffer(), toFill.getLen(), false);
@@ -1010,11 +1007,8 @@ void IGXMLScanner::sendCharData(XMLBuffer& toSend)
                     ((SchemaValidator*) fValidator)->setDatatypeBuffer(toFill.getRawBuffer());
 
                     // call all active identity constraints
-                    unsigned int count = fMatcherStack->getMatcherCount();
-
-                    for (unsigned int i = 0; i < count; i++) {
-                        fMatcherStack->getMatcherAt(i)->docCharacters(toFill.getRawBuffer(), toFill.getLen());
-                    }
+                    if (fMatcherStack->getMatcherCount())
+                        fContent.append(toFill.getRawBuffer(), toFill.getLen());
 
                     if (fDocHandler)
                         fDocHandler->docCharacters(toFill.getRawBuffer(), toFill.getLen(), false);
@@ -1031,11 +1025,8 @@ void IGXMLScanner::sendCharData(XMLBuffer& toSend)
         // call all active identity constraints
         if (fGrammarType == Grammar::SchemaGrammarType) {
 
-            unsigned int count = fMatcherStack->getMatcherCount();
-
-            for (unsigned int i = 0; i < count; i++) {
-                fMatcherStack->getMatcherAt(i)->docCharacters(toSend.getRawBuffer(), toSend.getLen());
-            }
+            if (fMatcherStack->getMatcherCount())
+                fContent.append(toSend.getRawBuffer(), toSend.getLen());
         }
 
         // Always assume its just char data if not validating
@@ -1953,12 +1944,8 @@ void IGXMLScanner::scanCDSection()
         {
             if (fGrammarType == Grammar::SchemaGrammarType) {
 
-                // call all active identity constraints
-                unsigned int count = fMatcherStack->getMatcherCount();
-
-                for (unsigned int i = 0; i < count; i++) {
-                    fMatcherStack->getMatcherAt(i)->docCharacters(bbCData.getRawBuffer(), bbCData.getLen());
-                }
+                if (fMatcherStack->getMatcherCount())
+                    fContent.append(bbCData.getRawBuffer(), bbCData.getLen());
             }
 
             // If we have a doc handler, call it
diff --git a/src/xercesc/internal/SGXMLScanner.cpp b/src/xercesc/internal/SGXMLScanner.cpp
index 88894f0f35dc665bd7df5b0981a2427e59015b56..74dc64855f19de9aa9f64b2ac0f3fdd91565141b 100644
--- a/src/xercesc/internal/SGXMLScanner.cpp
+++ b/src/xercesc/internal/SGXMLScanner.cpp
@@ -971,7 +971,7 @@ void SGXMLScanner::scanEndTag(bool& gotData)
             for (int i = oldCount - 1; i >= 0; i--) {
 
                 XPathMatcher* matcher = fMatcherStack->getMatcherAt(i);
-                matcher->endElement(*(topElem->fThisElement));
+                matcher->endElement(*(topElem->fThisElement), fContent.getRawBuffer());
             }
 
             if (fMatcherStack->size() > 0) {
@@ -986,14 +986,8 @@ void SGXMLScanner::scanEndTag(bool& gotData)
                 XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
                 IdentityConstraint* ic = matcher->getIdentityConstraint();
 
-                if (ic  && (ic->getType() != IdentityConstraint::KEYREF)) {
-
-                    matcher->endDocumentFragment();
+                if (ic  && (ic->getType() != IdentityConstraint::KEYREF))
                     fValueStoreCache->transplant(ic, matcher->getInitialDepth());
-                }
-                else if (!ic) {
-                    matcher->endDocumentFragment();
-                }
             }
 
             // now handle keyref's...
@@ -1009,8 +1003,6 @@ void SGXMLScanner::scanEndTag(bool& gotData)
                     if (values) { // nothing to do if nothing matched!
                         values->endDcocumentFragment(fValueStoreCache);
                     }
-
-                    matcher->endDocumentFragment();
                 }
             }
 
@@ -1082,6 +1074,9 @@ bool SGXMLScanner::scanStartTag(bool& gotData)
     //  ever be false if this is the root and its empty.
     gotData = true;
 
+    // Reset element content
+    fContent.reset();
+
     //  The current position is after the open bracket, so we need to read in
     //  in the element name.
     if (!fReaderMgr.getName(fQNameBuf))
@@ -1546,7 +1541,7 @@ bool SGXMLScanner::scanStartTag(bool& gotData)
                 for (int i = oldCount - 1; i >= 0; i--) {
 
                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(i);
-                    matcher->endElement(*elemDecl);
+                    matcher->endElement(*elemDecl, fContent.getRawBuffer());
                 }
 
                 if (fMatcherStack->size() > 0) {
@@ -1561,14 +1556,8 @@ bool SGXMLScanner::scanStartTag(bool& gotData)
                     XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
                     IdentityConstraint* ic = matcher->getIdentityConstraint();
 
-                    if (ic  && (ic->getType() != IdentityConstraint::KEYREF)) {
-
-                        matcher->endDocumentFragment();
+                    if (ic  && (ic->getType() != IdentityConstraint::KEYREF))
                         fValueStoreCache->transplant(ic, matcher->getInitialDepth());
-                    }
-                    else if (!ic) {
-                        matcher->endDocumentFragment();
-                    }
                 }
 
                 // now handle keyref's...
@@ -1584,8 +1573,6 @@ bool SGXMLScanner::scanStartTag(bool& gotData)
                         if (values) { // nothing to do if nothing matched!
                             values->endDcocumentFragment(fValueStoreCache);
                         }
-
-                        matcher->endDocumentFragment();
                     }
                 }
 
@@ -2699,11 +2686,8 @@ void SGXMLScanner::sendCharData(XMLBuffer& toSend)
                 ((SchemaValidator*) fValidator)->setDatatypeBuffer(toFill.getRawBuffer());
 
                 // call all active identity constraints
-                unsigned int count = fMatcherStack->getMatcherCount();
-
-                for (unsigned int i = 0; i < count; i++) {
-                    fMatcherStack->getMatcherAt(i)->docCharacters(toFill.getRawBuffer(), toFill.getLen());
-                }
+                if (fMatcherStack->getMatcherCount())
+                    fContent.append(toFill.getRawBuffer(), toFill.getLen());
 
                 if (fDocHandler)
                     fDocHandler->docCharacters(toFill.getRawBuffer(), toFill.getLen(), false);
@@ -2736,11 +2720,8 @@ void SGXMLScanner::sendCharData(XMLBuffer& toSend)
                 ((SchemaValidator*) fValidator)->setDatatypeBuffer(toFill.getRawBuffer());
 
                 // call all active identity constraints
-                unsigned int count = fMatcherStack->getMatcherCount();
-
-                for (unsigned int i = 0; i < count; i++) {
-                    fMatcherStack->getMatcherAt(i)->docCharacters(toFill.getRawBuffer(), toFill.getLen());
-                }
+                if (fMatcherStack->getMatcherCount())
+                    fContent.append(toFill.getRawBuffer(), toFill.getLen());
 
                 if (fDocHandler)
                     fDocHandler->docCharacters(toFill.getRawBuffer(), toFill.getLen(), false);
@@ -2754,11 +2735,8 @@ void SGXMLScanner::sendCharData(XMLBuffer& toSend)
     else
     {
         // call all active identity constraints
-        unsigned int count = fMatcherStack->getMatcherCount();
-
-        for (unsigned int i = 0; i < count; i++) {
-            fMatcherStack->getMatcherAt(i)->docCharacters(toSend.getRawBuffer(), toSend.getLen());
-        }
+        if (fMatcherStack->getMatcherCount())
+            fContent.append(toSend.getRawBuffer(), toSend.getLen());
 
         // Always assume its just char data if not validating
         if (fDocHandler)
@@ -3439,11 +3417,8 @@ void SGXMLScanner::scanCDSection()
                 emitError(XMLErrs::Expected2ndSurrogateChar);
 
             // call all active identity constraints
-            unsigned int count = fMatcherStack->getMatcherCount();
-
-            for (unsigned int i = 0; i < count; i++) {
-                fMatcherStack->getMatcherAt(i)->docCharacters(bbCData.getRawBuffer(), bbCData.getLen());
-            }
+            if (fMatcherStack->getMatcherCount())
+                fContent.append(bbCData.getRawBuffer(), bbCData.getLen());
 
             // If we have a doc handler, call it
             if (fDocHandler)
diff --git a/src/xercesc/internal/SGXMLScanner.hpp b/src/xercesc/internal/SGXMLScanner.hpp
index 665809bec28f4a64d930e3acd71ef13f25e82536..9474586c472afdce9bd8d6f5649212e6acfc6b02 100644
--- a/src/xercesc/internal/SGXMLScanner.hpp
+++ b/src/xercesc/internal/SGXMLScanner.hpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.2  2003/01/13 16:30:18  knoaman
+ * [Bug 14469] Validator doesn't enforce xsd:key.
+ *
  * Revision 1.1  2002/12/05 16:19:27  knoaman
  * Initial check-in.
  *
@@ -286,6 +289,7 @@ private :
     unsigned int                fElemStateSize;
     unsigned int*               fElemState;
     ElemStack                   fElemStack;
+    XMLBuffer                   fContent;
     ValueHashTableOf<XMLCh>*    fEntityTable;
     RefVectorOf<KVStringPair>*  fRawAttrList;
     SchemaGrammar*              fSchemaGrammar;
diff --git a/src/xercesc/validators/schema/identity/IC_Field.cpp b/src/xercesc/validators/schema/identity/IC_Field.cpp
index 66ae8159ba407c8f34de08c4b0549b108d144db7..813fe5f72d1a3bb52c02f6b158a6eeac3c0e4ed4 100644
--- a/src/xercesc/validators/schema/identity/IC_Field.cpp
+++ b/src/xercesc/validators/schema/identity/IC_Field.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.3  2003/01/13 16:30:19  knoaman
+ * [Bug 14469] Validator doesn't enforce xsd:key.
+ *
  * Revision 1.2  2002/11/04 14:47:41  tng
  * C++ Namespace Support.
  *
@@ -84,7 +87,7 @@ XERCES_CPP_NAMESPACE_BEGIN
 // ---------------------------------------------------------------------------
 FieldMatcher::FieldMatcher(XercesXPath* const xpath, IC_Field* const aField,
                            ValueStore* const valueStore)
-    : XPathMatcher(xpath, true, 0)
+    : XPathMatcher(xpath, 0)
     , fField(aField)
     , fValueStore(valueStore)
 {
diff --git a/src/xercesc/validators/schema/identity/IC_Selector.cpp b/src/xercesc/validators/schema/identity/IC_Selector.cpp
index f322ae9bf4ca9346af49708ed92f684c1fb123f6..25954f93a726ddb0cd2cd8279184d9d0c8f58d57 100644
--- a/src/xercesc/validators/schema/identity/IC_Selector.cpp
+++ b/src/xercesc/validators/schema/identity/IC_Selector.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.4  2003/01/13 16:30:19  knoaman
+ * [Bug 14469] Validator doesn't enforce xsd:key.
+ *
  * Revision 1.3  2002/11/04 14:47:41  tng
  * C++ Namespace Support.
  *
@@ -94,7 +97,7 @@ SelectorMatcher::SelectorMatcher(XercesXPath* const xpath,
                                  IC_Selector* const selector,
                                  FieldActivator* const fieldActivator,
                                  const int initialDepth)
-    : XPathMatcher(xpath, false, selector->getIdentityConstraint())
+    : XPathMatcher(xpath, selector->getIdentityConstraint())
     , fInitialDepth(initialDepth)
     , fElementDepth(0)
     , fMatchedDepth(-1)
@@ -123,7 +126,9 @@ void SelectorMatcher::startElement(const XMLElementDecl& elemDecl,
     fElementDepth++;
 
     // activate the fields, if selector is matched
-    if (fMatchedDepth == -1 && isMatched()) {
+    int matched = isMatched();
+    if ((fMatchedDepth == -1 && ((matched & XP_MATCHED) == XP_MATCHED))
+        || ((matched & XP_MATCHED_D) == XP_MATCHED_D)) {
 
         IdentityConstraint* ic = fSelector->getIdentityConstraint();
         int count = ic->getFieldCount();
@@ -133,17 +138,16 @@ void SelectorMatcher::startElement(const XMLElementDecl& elemDecl,
 
         for (int i = 0; i < count; i++) {
 
-            IC_Field* field = ic->getFieldAt(i);
-            XPathMatcher* matcher = fFieldActivator->activateField(field, fInitialDepth);
-
+            XPathMatcher* matcher = fFieldActivator->activateField(ic->getFieldAt(i), fInitialDepth);
             matcher->startElement(elemDecl, urlId, elemPrefix, attrList, attrCount);
         }
     }
 }
 
-void SelectorMatcher::endElement(const XMLElementDecl& elemDecl) {
+void SelectorMatcher::endElement(const XMLElementDecl& elemDecl,
+                                 const XMLCh* const elemContent) {
 
-    XPathMatcher::endElement(elemDecl);
+    XPathMatcher::endElement(elemDecl, elemContent);
 
     if (fElementDepth-- == fMatchedDepth) {
 
diff --git a/src/xercesc/validators/schema/identity/IC_Selector.hpp b/src/xercesc/validators/schema/identity/IC_Selector.hpp
index 3285b683bece40450569d460cc70abc0087d6298..395277a839e4dbea59e0c0d86ee82818648f3910 100644
--- a/src/xercesc/validators/schema/identity/IC_Selector.hpp
+++ b/src/xercesc/validators/schema/identity/IC_Selector.hpp
@@ -136,7 +136,8 @@ public:
                       const XMLCh* const elemPrefix,
 		              const RefVectorOf<XMLAttr>& attrList,
                       const unsigned int attrCount);
-    void endElement(const XMLElementDecl& elemDecl);
+    void endElement(const XMLElementDecl& elemDecl,
+                    const XMLCh* const elemContent);
 
 private:
     // -----------------------------------------------------------------------
diff --git a/src/xercesc/validators/schema/identity/XPathMatcher.cpp b/src/xercesc/validators/schema/identity/XPathMatcher.cpp
index 192e919cbb7804e0e15dd658997a8044265568c2..8605c96d68bc47a1185f684cacf4e70bdcc53cca 100644
--- a/src/xercesc/validators/schema/identity/XPathMatcher.cpp
+++ b/src/xercesc/validators/schema/identity/XPathMatcher.cpp
@@ -56,6 +56,9 @@
 
 /*
  * $Log$
+ * Revision 1.5  2003/01/13 16:30:19  knoaman
+ * [Bug 14469] Validator doesn't enforce xsd:key.
+ *
  * Revision 1.4  2002/11/04 14:47:41  tng
  * C++ Namespace Support.
  *
@@ -92,16 +95,13 @@ XERCES_CPP_NAMESPACE_BEGIN
 //  XPathMatcher: Constructors and Destructor
 // ---------------------------------------------------------------------------
 XPathMatcher::XPathMatcher(XercesXPath* const xpath)
-    : fShouldBufferContent(false)
-    , fBufferContent(false)
-    , fLocationPathSize(0)
+    : fLocationPathSize(0)
     , fMatched(0)
     , fNoMatchDepth(0)
     , fCurrentStep(0)
     , fStepIndexes(0)
     , fLocationPaths(0)
     , fIdentityConstraint(0)
-    , fMatchedBuffer(128)
 {
     try {
         init(xpath);
@@ -115,16 +115,14 @@ XPathMatcher::XPathMatcher(XercesXPath* const xpath)
 
 
 XPathMatcher::XPathMatcher(XercesXPath* const xpath,
-                           const bool shouldBufferContent,
                            IdentityConstraint* const ic)
-    : fShouldBufferContent(shouldBufferContent)
-    , fLocationPathSize(0)
+    : fLocationPathSize(0)
     , fMatched(0)
     , fNoMatchDepth(0)
     , fCurrentStep(0)
+    , fStepIndexes(0)
     , fLocationPaths(0)
     , fIdentityConstraint(ic)
-    , fMatchedBuffer(0)
 {
     try {
         init(xpath);
@@ -157,7 +155,7 @@ void XPathMatcher::init(XercesXPath* const xpath) {
             fStepIndexes = new RefVectorOf<ValueStackOf<int> >(fLocationPathSize);
             fCurrentStep = new int[fLocationPathSize];
             fNoMatchDepth = new int[fLocationPathSize];
-            fMatched = new bool[fLocationPathSize];
+            fMatched = new int[fLocationPathSize];
 
             for(unsigned int i=0; i < fLocationPathSize; i++) {
                 fStepIndexes->addElement(new ValueStackOf<int>(8));
@@ -166,30 +164,18 @@ void XPathMatcher::init(XercesXPath* const xpath) {
     }
 }
 
-void XPathMatcher::clear() {
-
-        fBufferContent = false;
-        fMatchedBuffer.reset();
-
-        for(int i = 0; i < (int) fLocationPathSize; i++)
-            fMatched[i] = false;
-
-}
 
 // ---------------------------------------------------------------------------
 //  XPathMatcher: XMLDocumentHandler methods
 // ---------------------------------------------------------------------------
 void XPathMatcher::startDocumentFragment() {
 
-    // reset state
-    clear();
-
     for(unsigned int i = 0; i < fLocationPathSize; i++) {
 
         fStepIndexes->elementAt(i)->removeAllElements();
         fCurrentStep[i] = 0;
         fNoMatchDepth[i] = 0;
-        fMatched[i] = false;
+        fMatched[i] = 0;
     }
 }
 
@@ -206,11 +192,15 @@ void XPathMatcher::startElement(const XMLElementDecl& elemDecl,
         fStepIndexes->elementAt(i)->push(startStep);
 
         // try next xpath, if not matching
-        if (fMatched[i] || fNoMatchDepth[i] > 0) {
+        if ((fMatched[i] & XP_MATCHED_D) == XP_MATCHED || fNoMatchDepth[i] > 0) {
             fNoMatchDepth[i]++;
             continue;
         }
 
+        if((fMatched[i] & XP_MATCHED_D) == XP_MATCHED_D) {
+            fMatched[i] = XP_MATCHED_DP;
+        }
+
         // consume self::node() steps
         XercesLocationPath* locPath = fLocationPaths->elementAt(i);
         int stepSize = locPath->getStepSize();
@@ -222,14 +212,7 @@ void XPathMatcher::startElement(const XMLElementDecl& elemDecl,
 
         if (fCurrentStep[i] == stepSize) {
 
-            fMatched[i] = true;
-            int j=0;
-
-            for(; j<i && !fMatched[j]; j++) ;
-
-            if(j==i)
-                fBufferContent = fShouldBufferContent;
-
+            fMatched[i] = XP_MATCHED;
             continue;
         }
 
@@ -244,6 +227,7 @@ void XPathMatcher::startElement(const XMLElementDecl& elemDecl,
             fCurrentStep[i]++;
         }
 
+        bool sawDescendant = fCurrentStep[i] > descendantStep;
         if (fCurrentStep[i] == stepSize) {
 
             fNoMatchDepth[i]++;
@@ -279,13 +263,14 @@ void XPathMatcher::startElement(const XMLElementDecl& elemDecl,
 
         if (fCurrentStep[i] == stepSize) {
 
-            fMatched[i] = true;
-            int j=0;
+            if (sawDescendant) {
 
-            for(; j<i && !fMatched[j]; j++) ;
-
-            if(j==i)
-                fBufferContent = fShouldBufferContent;
+                fCurrentStep[i] = descendantStep;
+                fMatched[i] = XP_MATCHED_D;
+            }
+            else {
+                fMatched[i] = XP_MATCHED;
+            }
 
             continue;
         }
@@ -309,10 +294,10 @@ void XPathMatcher::startElement(const XMLElementDecl& elemDecl,
 
                         if (fCurrentStep[i] == stepSize) {
 
-                            fMatched[i] = true;
+                            fMatched[i] = XP_MATCHED_A;
                             int j=0;
 
-                            for(; j<i && !fMatched[j]; j++) ;
+                            for(; j<i && ((fMatched[j] & XP_MATCHED) != XP_MATCHED); j++) ;
 
                             if(j == i) {
 
@@ -326,7 +311,7 @@ void XPathMatcher::startElement(const XMLElementDecl& elemDecl,
                 }
             }
 
-            if (!fMatched[i]) {
+            if ((fMatched[i] & XP_MATCHED) != XP_MATCHED) {
 
                 if(fCurrentStep[i] > descendantStep) {
 
@@ -340,24 +325,14 @@ void XPathMatcher::startElement(const XMLElementDecl& elemDecl,
     }
 }
 
-void XPathMatcher::docCharacters(const XMLCh* const chars,
-                                 const unsigned int length) {
-
-    // collect match content
-    // so long as one of our paths is matching, store the content
-    for(int i=0; i < (int) fLocationPathSize; i++) {
-
-        if (fBufferContent && fNoMatchDepth[i] == 0) {
-            fMatchedBuffer.append(chars, length);
-            break;
-        }
-    }
-}
-
-void XPathMatcher::endElement(const XMLElementDecl& elemDecl) {
+void XPathMatcher::endElement(const XMLElementDecl& elemDecl,
+                              const XMLCh* const elemContent) {
 
     for(int i = 0; i < (int) fLocationPathSize; i++) {
 
+        // go back a step
+        fCurrentStep[i] = fStepIndexes->elementAt(i)->pop();
+
         // don't do anything, if not matching
         if (fNoMatchDepth[i] > 0) {
             fNoMatchDepth[i]--;
@@ -366,47 +341,35 @@ void XPathMatcher::endElement(const XMLElementDecl& elemDecl) {
         else {
 
             int j=0;
+            for(; j<i && ((fMatched[j] & XP_MATCHED) != XP_MATCHED); j++) ;
 
-            for(; j<i && !fMatched[j]; j++) ;
-
-            if (j < i)
+            if (j < i || (fMatched[j] == 0)
+                || ((fMatched[j] & XP_MATCHED_A) == XP_MATCHED_A))
 				continue;
 
-            if (fBufferContent) {
+            DatatypeValidator* dv = ((SchemaElementDecl*) &elemDecl)->getDatatypeValidator();
+            bool isNillable = (((SchemaElementDecl *) &elemDecl)->getMiscFlags() & SchemaSymbols::NILLABLE) != 0;
 
-                DatatypeValidator* dv = ((SchemaElementDecl*) &elemDecl)->getDatatypeValidator();
-                bool isNillable = (((SchemaElementDecl *) &elemDecl)->getMiscFlags() & SchemaSymbols::NILLABLE) != 0;
-
-                fBufferContent = false;
-                matched(fMatchedBuffer.getRawBuffer(), dv, isNillable);
-            }
-
-            clear();
+            matched(elemContent, dv, isNillable);
+            fMatched[i] = 0;
         }
-
-        // go back a step
-        fCurrentStep[i] = fStepIndexes->elementAt(i)->pop();
     }
 }
 
-void XPathMatcher::endDocumentFragment() {
-
-    clear();
-}
-
 
 // ---------------------------------------------------------------------------
 //  XPathMatcher: Match methods
 // ---------------------------------------------------------------------------
-bool XPathMatcher::isMatched() {
+int XPathMatcher::isMatched() {
 
     // xpath has been matched if any one of the members of the union have matched.
     for (int i=0; i < (int) fLocationPathSize; i++) {
-        if (fMatched[i])
-            return true;
+        if (((fMatched[i] & XP_MATCHED) == XP_MATCHED)
+            && ((fMatched[i] & XP_MATCHED_DP) != XP_MATCHED_DP))
+            return fMatched[i];
     }
 
-    return false;
+    return 0;
 }
 
 void XPathMatcher::matched(const XMLCh* const content,
diff --git a/src/xercesc/validators/schema/identity/XPathMatcher.hpp b/src/xercesc/validators/schema/identity/XPathMatcher.hpp
index 37be6ed6f88c1e9dace784fc6bb5fe1322fef02c..db7cae23468b4a9276b11bc172c20d9f2a95610e 100644
--- a/src/xercesc/validators/schema/identity/XPathMatcher.hpp
+++ b/src/xercesc/validators/schema/identity/XPathMatcher.hpp
@@ -89,7 +89,7 @@ public:
     //  Constructors/Destructor
     // -----------------------------------------------------------------------
     XPathMatcher(XercesXPath* const xpath);
-    XPathMatcher(XercesXPath* const xpath, const bool shouldBufferContent,
+    XPathMatcher(XercesXPath* const xpath,
                  IdentityConstraint* const ic);
     virtual ~XPathMatcher();
 
@@ -104,23 +104,32 @@ public:
     /**
       * Returns true if XPath has been matched.
       */
-    bool isMatched();
+    int isMatched();
     virtual int getInitialDepth() const;
 
     // -----------------------------------------------------------------------
     //  XMLDocumentHandler methods
     // -----------------------------------------------------------------------
     virtual void startDocumentFragment();
-    virtual void endDocumentFragment();
     virtual void startElement(const XMLElementDecl& elemDecl,
                               const unsigned int urlId,
                               const XMLCh* const elemPrefix,
                               const RefVectorOf<XMLAttr>& attrList,
                               const unsigned int attrCount);
-    virtual void endElement(const XMLElementDecl& elemDecl);
-    virtual void docCharacters(const XMLCh* const chars, const unsigned int length);
+    virtual void endElement(const XMLElementDecl& elemDecl,
+                            const XMLCh* const elemContent);
 
 protected:
+
+    enum
+    {
+        XP_MATCHED = 1        // matched any way
+        , XP_MATCHED_A = 3    // matched on the attribute axis
+        , XP_MATCHED_D = 5    // matched on the descendant-or-self axixs
+        , XP_MATCHED_DP = 13  // matched some previous (ancestor) node on the
+                              // descendant-or-self-axis, but not this node
+    };
+
     // -----------------------------------------------------------------------
     //  Match methods
     // -----------------------------------------------------------------------
@@ -133,26 +142,16 @@ protected:
                          DatatypeValidator* const dv, const bool isNil);
 
 private:
+
     // -----------------------------------------------------------------------
     //  Helper methods
     // -----------------------------------------------------------------------
     void init(XercesXPath* const xpath);
     void cleanUp();
 
-    /**
-      * Clears the match values.
-      */
-    void clear();
-
     // -----------------------------------------------------------------------
     //  Data members
     //
-    //  fShouldBufferContent
-    //      Application preference to buffer content or not.
-    //
-    //  fBufferContent
-    //      True, if we should buffer character content at this time.
-    //
     //  fMatched
     //      Indicates whether XPath has been matched or not
     //
@@ -174,19 +173,14 @@ private:
     //      The identity constraint we're the matcher for.  Only used for
     //      selectors.
     //
-    //  fMatchedBuffer
-    //      To hold match text.
     // -----------------------------------------------------------------------
-    bool                             fShouldBufferContent;
-    bool                             fBufferContent;
     unsigned int                     fLocationPathSize;
-    bool*                            fMatched;
+    int*                             fMatched;
     int*                             fNoMatchDepth;
     int*                             fCurrentStep;
     RefVectorOf<ValueStackOf<int> >* fStepIndexes;
     RefVectorOf<XercesLocationPath>* fLocationPaths;
     IdentityConstraint*              fIdentityConstraint;
-    XMLBuffer                        fMatchedBuffer;
 };
 
 // ---------------------------------------------------------------------------