You are viewing a plain text version of this content. The canonical link for it is here.
Posted to general@xerces.apache.org by "George T. Joseph" <gt...@peakin.com> on 2000/02/10 23:03:05 UTC

Patch for ElementDeclPool.java

There's been a nagging problem with ID/IDREF referential integrity error
reporting.  If an IDREF isn't found among the declared IDs, the location of the
error is always reported as the last line in the root XML instance document.
This happens because the check isn't done until all documents have been parsed
and otherwise validated.  That makes sense, but it also makes it hard to locate
the actual error, especially if there are a lot of external entities involved.

So...ElementDeclPool already adds each IDREF attribute to an internal Hashtable
(with a dummy value object) as the document is being parsed.  Rather than
storing a dummy object, the live document Locator is cloned and saved instead.
Later when the Hashtable is enumerated and checked, if an IDREF isn't found in
the pool of IDs, the Locator saved with the IDREF is used to report the error
rather than the live one which, by that time, would be pointing to the end of
the file.

In performance testing with files of 5000 elements, each with an ID/IDREF pair
of attributes, there was virtually no performance difference with this patch in
versus out.

george


*** xml-xerces/java/src/org/apache/xerces/validators/dtd/ElementDeclPool.java
Mon Nov 08 20:11:52 1999
--- src/org/apache/xerces/validators/dtd/ElementDeclPool.java	Wed Feb 09
16:20:30 2000
***************
*** 65,71 ****

  import org.xml.sax.Locator;
  import org.xml.sax.SAXParseException;
!
  import java.util.StringTokenizer;
  import java.util.Enumeration;
  import java.util.Hashtable;
--- 65,71 ----

  import org.xml.sax.Locator;
  import org.xml.sax.SAXParseException;
! import org.xml.sax.helpers.LocatorImpl;
  import java.util.StringTokenizer;
  import java.util.Enumeration;
  import java.util.Hashtable;
***************
*** 931,939 ****
              fIdRefs = new Hashtable();
          else if (fIdRefs.containsKey(key))
              return;
!         if (fNullValue == null)
!             fNullValue = new Object();
!         fIdRefs.put(key, fNullValue/*new Integer(elementType)*/);
      }
      public void checkIdRefs() throws Exception {
          if (fIdRefs == null)
--- 931,937 ----
              fIdRefs = new Hashtable();
          else if (fIdRefs.containsKey(key))
              return;
!         fIdRefs.put(key, new LocatorImpl(fErrorReporter.getLocator()));
      }
      public void checkIdRefs() throws Exception {
          if (fIdRefs == null)
***************
*** 943,949 ****
              Integer key = (Integer)en.nextElement();
              if (fIdDefs == null || !fIdDefs.containsKey(key)) {
                  Object[] args = { fStringPool.toString(key.intValue()) };
!                 fErrorReporter.reportError(fErrorReporter.getLocator(),
                                             XMLMessages.XML_DOMAIN,

XMLMessages.MSG_ELEMENT_WITH_ID_REQUIRED,
                                             XMLMessages.VC_IDREF,
--- 941,949 ----
              Integer key = (Integer)en.nextElement();
              if (fIdDefs == null || !fIdDefs.containsKey(key)) {
                  Object[] args = { fStringPool.toString(key.intValue()) };
! 					 Locator loc = (Locator)fIdRefs.get(key);
! 					 if (loc == null) loc = fErrorReporter.getLocator();
!                 fErrorReporter.reportError(loc,
                                             XMLMessages.XML_DOMAIN,

XMLMessages.MSG_ELEMENT_WITH_ID_REQUIRED,
                                             XMLMessages.VC_IDREF,