You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xerces.apache.org by Jacob Kjome <ho...@visi.com> on 2006/09/23 08:44:20 UTC

Re: Why does HTMLDocumentImpl need to override getElementById(String) ???

At 02:06 PM 9/22/2006, you wrote:
 >Jacob Kjome <ho...@visi.com> wrote on 09/22/2006 12:17:53 PM:
 >
 >> Quoting Michael Glavassevich <mr...@ca.ibm.com>:
 >>
 >> > I imagine it was overridden because the getElementById() defined by
 >DOM
 >> > HTML [1] (IDs are attributes named "id") has different behaviour than
 >the
 >> > one in DOM Core [2] (IDs are attributes of type ID).
 >>
 >> But the HTML4.01 DTD defines "id" as of type ID...
 >> http://www.w3.org/TR/html4/sgml/dtd.html#coreattrs
 >
 >And if the document has no DTD or references a different DTD which
 >declares "id" to be some other type then it isn't an ID. The "identifiers"
 >map only includes elements which have an ID attribute (see
 >http://xerces.apache.org/xerces2-j/javadocs/api/org/w3c/dom/Attr.html#isId()). 

 >Since HTML DOM treats "id" as an ID irrespective of what its declared type
 >is there's no guarantee that you'll find it in the map.
 >
 >> > There probably wasn't
 >> > much thought about making it efficient and since there's really no one
 >> > maintaining the HTML DOM implementation it hasn't improved much over
 >the
 >> > years.
 >> >
 >>
 >> Point taken, but how much effort do you think it would be?  If the
 >> HTML4.01 DTD
 >> defines "id" as of type ID, then couldn't Xerces track these id's in the
 >> "identifiers" map while building the document?
 >
 >Sure, if "id" has been declared in the DTD then it will be in the map.
 >
 >> I'm talking about
 >> the DOMParser
 >> building it using an HTML parser configuration such as that provided by
 >> NekoHTML.  Or is it up to NekoHTML to ensure this happens?
 >
 >NekoHTML might auto-magically assign the type of these attributes to ID
 >but a conforming XML parser won't.
 >
 >> Should I be talking to you or Andy Clark?
 >
 >Andy would know better than anyone else. (I've never used NekoHTML.)
 >

I've got a question out to Andy on this.  I'll let you know what I find out.


 >> Ultimately, would you accept a change in HTMLDocumentImpl to let
 >thesuperclass
 >> determine the Id from it's internal "identifiers" map or would that
 >introduce
 >> more risk than you are willing to accept; that the parser might not
 >populate
 >> the "identifiers" map for HTML?
 >> Of course, it could implemented to fall back
 >> to existing behavior if the parent class can't find it in the
 >> "identifiers" map
 >> (or the map is null), allowing for optimized behavior for parsers
 >> that choose to
 >> properly populate the map and safe fallback for parsers that don't.
 >>
 >> What do you think?
 >
 >Provided the method (fallback included) continues to do what the DOM HTML
 >spec says that should be fine. Are you planning to contribute a patch? :-)
 >

What do you think of this (below).  It actually goes one step further 
by not necessarily counting on the parsing process to build up the 
"identifiers" map.  It first checks super.getElementById() (which 
uses the "identifiers" map).  If it finds the element, it returns it 
immediately.  No unnecessary recursion.  If it doesn't find it, it 
falls back to the pre-existing recursive behavior to find the 
element.  If it is found, it populates the "identifiers" map with the 
element so the next call to getElementById() will be 
optimized.  Finally, it returns the element.

     public synchronized Element getElementById( String elementId )
     {
         Element idElement = super.getElementById(elementId);
         if (idElement != null) {
             return idElement;
         }
         idElement = getElementById( elementId, this );
         if (idElement != null) {
             putIdentifier(elementId, idElement);
         }
         return idElement;
     }

What do you think?  With this in place, even if no parse-time 
solution is found for HTML documents to populate the "identifiers" 
map, there's still some optimization provided in the case that 
getElementById() is called more than once on the same Id.  I know, 
it's kind of odd, but there are some situations where such a thing 
happens and it doesn't hurt anything to account for it.  And with a 
parse-time solution, the less efficient recursion will never have to 
be run because "identifiers" map will already have been populated 
allowing for fully optimized access to elements with Ids.

Now, hopefully I'll get a good answer from Andy so I can take full 
advantage of the optimization!


later,

Jake

 >> Jake
 >>
 >> > [1]
 >http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-html.html
 >> > [2]
 >> > http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.
 >> html#ID-getElBId
 >> >
 >> > Michael Glavassevich
 >> > XML Parser Development
 >> > IBM Toronto Lab
 >> > E-mail: mrglavas@ca.ibm.com
 >> > E-mail: mrglavas@apache.org
 >
 >Thanks.
 >
 >Michael Glavassevich
 >XML Parser Development
 >IBM Toronto Lab
 >E-mail: mrglavas@ca.ibm.com
 >E-mail: mrglavas@apache.org
 >
 >---------------------------------------------------------------------
 >To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
 >For additional commands, e-mail: j-users-help@xerces.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org


Re: Why does HTMLDocumentImpl need to override getElementById(String) ???

Posted by Jacob Kjome <ho...@visi.com>.
At 11:23 AM 9/30/2006, you wrote:
 >Thanks Jake. It looks good. I just committed it to SVN.
 >

Excellent!  Thanks Michael :-)

Jake

 >Michael Glavassevich
 >XML Parser Development
 >IBM Toronto Lab
 >E-mail: mrglavas@ca.ibm.com
 >E-mail: mrglavas@apache.org
 >
 >Jacob Kjome <ho...@visi.com> wrote on 09/30/2006 11:05:26 AM:
 >
 >>
 >> Hi Michael,
 >>
 >> Please see the new "improvement" report I just submitted in Jira with
 >> a patch included.  I tried to explain everything about the patch
 >> there.  Let me know if you have questions or objections.
 >>
 >> http://issues.apache.org/jira/browse/XERCESJ-1200
 >>
 >>
 >> Jake
 >>
 >>
 >> ---------------------------------------------------------------------
 >> To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
 >> For additional commands, e-mail: j-users-help@xerces.apache.org
 >
 >
 >---------------------------------------------------------------------
 >To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
 >For additional commands, e-mail: j-users-help@xerces.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org


Re: Why does HTMLDocumentImpl need to override getElementById(String) ???

Posted by Michael Glavassevich <mr...@ca.ibm.com>.
Thanks Jake. It looks good. I just committed it to SVN.

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: mrglavas@ca.ibm.com
E-mail: mrglavas@apache.org

Jacob Kjome <ho...@visi.com> wrote on 09/30/2006 11:05:26 AM:

> 
> Hi Michael,
> 
> Please see the new "improvement" report I just submitted in Jira with 
> a patch included.  I tried to explain everything about the patch 
> there.  Let me know if you have questions or objections.
> 
> http://issues.apache.org/jira/browse/XERCESJ-1200
> 
> 
> Jake 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
> For additional commands, e-mail: j-users-help@xerces.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org


Re: Why does HTMLDocumentImpl need to override getElementById(String) ???

Posted by Jacob Kjome <ho...@visi.com>.
Hi Michael,

Please see the new "improvement" report I just submitted in Jira with 
a patch included.  I tried to explain everything about the patch 
there.  Let me know if you have questions or objections.

http://issues.apache.org/jira/browse/XERCESJ-1200


Jake 


---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org


Re: Why does HTMLDocumentImpl need to override getElementById(String) ???

Posted by Michael Glavassevich <mr...@ca.ibm.com>.
Jacob Kjome <ho...@visi.com> wrote on 09/27/2006 01:58:48 PM:

> Quoting Michael Glavassevich <mr...@ca.ibm.com>:
> 
> > Hi Jake,
> >
> > Jacob Kjome <ho...@visi.com> wrote on 09/24/2006 11:46:57 PM:
> >
> > <snip/>
> >
> > > Ok, then how about...
> > >
> > >      public synchronized Element getElementById( String elementId )
> > >      {
> > >          Element idElement = super.getElementById(elementId);
> > >          if (idElement != null) {
> > >              return idElement;
> > >          }
> > >          idElement = getElementById( elementId, this );
> > >          if (idElement != null) {
> > >              idElement.setIdAttribute("id", true);
> > >          }
> > >          return idElement;
> > >      }
> > >
> > > That seems to work just as well and seems like it addresses the 
issue
> > > you just mentioned, no?
> >
> > Hmmm.... That's still going to have some wonky behaviour. Consider the
> > following code snippet:
> >
> > Document doc = ...;
> > Attr id = ...; // name = "id", value = "foo"
> > System.out.println(id.isId()); // false
> > doc.getElementById("foo");
> > System.out.println(id.isId()); // true
> > doc.normalizeDocument(); // validate
> > System.out.println(id.isId()); // false
> >
> > The IDness of "id" will change as a side-effect of calling
> > getElementById() and/or normalizeDocument(). If this attribute really 
is
> > an ID isId() should always return true. Perhaps a better way to 
address
> > this would be for the HTML DOM to enforce the IDness of these 
attributes
> > and store their values in the "identifiers" map as they're added to 
the
> > tree.
> >
> 
> I'm not looking at the Xerces HTML DOM code right now (I will when Iget 
home),
> but do you have the feeling that this can be centrally managed, or will 
there
> have to be code in multiple places to manage this?
>
> That is, can 
> code simply be
> added to Element.setAttributXXX() methods to check for the 
attributebeing "id"
> and, if so, call the applicable this.setIdAttribute() method?  If so, 
that
> sounds like a pretty simple change and should work in all 
> situations.  And then
> getElementById() in HTMLDocumentImpl can simply be commented out to let 
the
> superclass's method do the work by pulling it from the "identifiers" 
map.
> 
> Thoughts?

It's probably a bit more than catching the "id" attributes when they're 
added. For instance, you probably need to do something for 
normalizeDocument() like walking the tree to restore the IDness of each 
"id" attribute.

> Jake
> 
> > > Jake
> > >
> > > 
---------------------------------------------------------------------
> > > To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
> > > For additional commands, e-mail: j-users-help@xerces.apache.org
> >
> > Michael Glavassevich
> > XML Parser Development
> > IBM Toronto Lab
> > E-mail: mrglavas@ca.ibm.com
> > E-mail: mrglavas@apache.org
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
> > For additional commands, e-mail: j-users-help@xerces.apache.org
> >
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
> For additional commands, e-mail: j-users-help@xerces.apache.org

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: mrglavas@ca.ibm.com
E-mail: mrglavas@apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org


Re: Why does HTMLDocumentImpl need to override getElementById(String) ???

Posted by Jacob Kjome <ho...@visi.com>.
Quoting Michael Glavassevich <mr...@ca.ibm.com>:

> Hi Jake,
>
> Jacob Kjome <ho...@visi.com> wrote on 09/24/2006 11:46:57 PM:
>
> <snip/>
>
> > Ok, then how about...
> >
> >      public synchronized Element getElementById( String elementId )
> >      {
> >          Element idElement = super.getElementById(elementId);
> >          if (idElement != null) {
> >              return idElement;
> >          }
> >          idElement = getElementById( elementId, this );
> >          if (idElement != null) {
> >              idElement.setIdAttribute("id", true);
> >          }
> >          return idElement;
> >      }
> >
> > That seems to work just as well and seems like it addresses the issue
> > you just mentioned, no?
>
> Hmmm.... That's still going to have some wonky behaviour. Consider the
> following code snippet:
>
> Document doc = ...;
> Attr id = ...; // name = "id", value = "foo"
> System.out.println(id.isId()); // false
> doc.getElementById("foo");
> System.out.println(id.isId()); // true
> doc.normalizeDocument(); // validate
> System.out.println(id.isId()); // false
>
> The IDness of "id" will change as a side-effect of calling
> getElementById() and/or normalizeDocument(). If this attribute really is
> an ID isId() should always return true. Perhaps a better way to address
> this would be for the HTML DOM to enforce the IDness of these attributes
> and store their values in the "identifiers" map as they're added to the
> tree.
>

I'm not looking at the Xerces HTML DOM code right now (I will when I get home),
but do you have the feeling that this can be centrally managed, or will there
have to be code in multiple places to manage this?  That is, can code simply be
added to Element.setAttributXXX() methods to check for the attribute being "id"
and, if so, call the applicable this.setIdAttribute() method?  If so, that
sounds like a pretty simple change and should work in all situations.  And then
getElementById() in HTMLDocumentImpl can simply be commented out to let the
superclass's method do the work by pulling it from the "identifiers" map.

Thoughts?

Jake

> > Jake
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
> > For additional commands, e-mail: j-users-help@xerces.apache.org
>
> Michael Glavassevich
> XML Parser Development
> IBM Toronto Lab
> E-mail: mrglavas@ca.ibm.com
> E-mail: mrglavas@apache.org
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
> For additional commands, e-mail: j-users-help@xerces.apache.org
>




---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org


Re: Why does HTMLDocumentImpl need to override getElementById(String) ???

Posted by Michael Glavassevich <mr...@ca.ibm.com>.
Hi Jake,

Jacob Kjome <ho...@visi.com> wrote on 09/24/2006 11:46:57 PM:

<snip/>

> Ok, then how about...
> 
>      public synchronized Element getElementById( String elementId )
>      {
>          Element idElement = super.getElementById(elementId);
>          if (idElement != null) {
>              return idElement;
>          }
>          idElement = getElementById( elementId, this );
>          if (idElement != null) {
>              idElement.setIdAttribute("id", true);
>          }
>          return idElement;
>      }
> 
> That seems to work just as well and seems like it addresses the issue 
> you just mentioned, no?

Hmmm.... That's still going to have some wonky behaviour. Consider the 
following code snippet:

Document doc = ...;
Attr id = ...; // name = "id", value = "foo"
System.out.println(id.isId()); // false
doc.getElementById("foo");
System.out.println(id.isId()); // true
doc.normalizeDocument(); // validate
System.out.println(id.isId()); // false

The IDness of "id" will change as a side-effect of calling 
getElementById() and/or normalizeDocument(). If this attribute really is 
an ID isId() should always return true. Perhaps a better way to address 
this would be for the HTML DOM to enforce the IDness of these attributes 
and store their values in the "identifiers" map as they're added to the 
tree.

> Jake
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
> For additional commands, e-mail: j-users-help@xerces.apache.org

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: mrglavas@ca.ibm.com
E-mail: mrglavas@apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org


Re: Why does HTMLDocumentImpl need to override getElementById(String) ???

Posted by Jacob Kjome <ho...@visi.com>.
At 02:41 PM 9/24/2006, you wrote:
 >Hi Jake,
 >
 >Jacob Kjome <ho...@visi.com> wrote on 09/23/2006 02:44:20 AM:
 >
 ><snip/>
 >
 >> What do you think of this (below).  It actually goes one step further
 >> by not necessarily counting on the parsing process to build up the
 >> "identifiers" map.  It first checks super.getElementById() (which
 >> uses the "identifiers" map).  If it finds the element, it returns it
 >> immediately.  No unnecessary recursion.  If it doesn't find it, it
 >> falls back to the pre-existing recursive behavior to find the
 >> element.  If it is found, it populates the "identifiers" map with the
 >> element so the next call to getElementById() will be
 >> optimized.  Finally, it returns the element.
 >>
 >>      public synchronized Element getElementById( String elementId )
 >>      {
 >>          Element idElement = super.getElementById(elementId);
 >>          if (idElement != null) {
 >>              return idElement;
 >>          }
 >>          idElement = getElementById( elementId, this );
 >>          if (idElement != null) {
 >>              putIdentifier(elementId, idElement);
 >>          }
 >>          return idElement;
 >>      }
 >>
 >> What do you think?  With this in place, even if no parse-time
 >> solution is found for HTML documents to populate the "identifiers"
 >> map, there's still some optimization provided in the case that
 >> getElementById() is called more than once on the same Id.  I know,
 >> it's kind of odd, but there are some situations where such a thing
 >> happens and it doesn't hurt anything to account for it.  And with a
 >> parse-time solution, the less efficient recursion will never have to
 >> be run because "identifiers" map will already have been populated
 >> allowing for fully optimized access to elements with Ids.
 >
 >I don't think that's going to work. If after caching the id in the
 >"identifiers" map the application changes the value of the id or removes
 >it from the element the "identifers" map won't get updated so a subsequent
 >call to getElementById() would return the wrong answer. Only modifications
 >to ID attributes [1] get reflected in this map.
 >

Ok, then how about...

     public synchronized Element getElementById( String elementId )
     {
         Element idElement = super.getElementById(elementId);
         if (idElement != null) {
             return idElement;
         }
         idElement = getElementById( elementId, this );
         if (idElement != null) {
             idElement.setIdAttribute("id", true);
         }
         return idElement;
     }

That seems to work just as well and seems like it addresses the issue 
you just mentioned, no?

Jake

 >
 >[1]
 >http://xerces.apache.org/xerces2-j/javadocs/api/org/w3c/dom/Attr.html#isId()
 >
 >Michael Glavassevich
 >XML Parser Development
 >IBM Toronto Lab
 >E-mail: mrglavas@ca.ibm.com
 >E-mail: mrglavas@apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org


Re: Why does HTMLDocumentImpl need to override getElementById(String) ???

Posted by Michael Glavassevich <mr...@ca.ibm.com>.
Hi Jake,

Jacob Kjome <ho...@visi.com> wrote on 09/23/2006 02:44:20 AM:

<snip/>

> What do you think of this (below).  It actually goes one step further 
> by not necessarily counting on the parsing process to build up the 
> "identifiers" map.  It first checks super.getElementById() (which 
> uses the "identifiers" map).  If it finds the element, it returns it 
> immediately.  No unnecessary recursion.  If it doesn't find it, it 
> falls back to the pre-existing recursive behavior to find the 
> element.  If it is found, it populates the "identifiers" map with the 
> element so the next call to getElementById() will be 
> optimized.  Finally, it returns the element.
> 
>      public synchronized Element getElementById( String elementId )
>      {
>          Element idElement = super.getElementById(elementId);
>          if (idElement != null) {
>              return idElement;
>          }
>          idElement = getElementById( elementId, this );
>          if (idElement != null) {
>              putIdentifier(elementId, idElement);
>          }
>          return idElement;
>      }
> 
> What do you think?  With this in place, even if no parse-time 
> solution is found for HTML documents to populate the "identifiers" 
> map, there's still some optimization provided in the case that 
> getElementById() is called more than once on the same Id.  I know, 
> it's kind of odd, but there are some situations where such a thing 
> happens and it doesn't hurt anything to account for it.  And with a 
> parse-time solution, the less efficient recursion will never have to 
> be run because "identifiers" map will already have been populated 
> allowing for fully optimized access to elements with Ids.

I don't think that's going to work. If after caching the id in the 
"identifiers" map the application changes the value of the id or removes 
it from the element the "identifers" map won't get updated so a subsequent 
call to getElementById() would return the wrong answer. Only modifications 
to ID attributes [1] get reflected in this map.

> Now, hopefully I'll get a good answer from Andy so I can take full 
> advantage of the optimization!
> 
> 
> later,
> 
> Jake
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
> For additional commands, e-mail: j-users-help@xerces.apache.org

[1] 
http://xerces.apache.org/xerces2-j/javadocs/api/org/w3c/dom/Attr.html#isId()

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: mrglavas@ca.ibm.com
E-mail: mrglavas@apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org