Re: DOM XPath and Text nodes

* Anne van Kesteren wrote:
>Apparently WebKit and Gecko violate the XPath specifications and return  
>more than one Text node if they are adjacent. I do not really care either  
>way, but I did create this wiki page to track problems with the current  
>XPath specification that need to be resolved in a future version (if  
>someone is ever going to write one that is):
>
>   http://wiki.whatwg.org/wiki/DOM_XPath

A test case would be

  var doc = new DOMParser().parseFromString("<y/>", "text/xml");
  var tx1 = doc.createTextNode("foo");
  var tx2 = doc.createTextNode("bar");
  doc.documentElement.appendChild(tx1);
  doc.documentElement.appendChild(tx2);
  var res = doc.evaluate("/*/text()", doc, null, 7, null);
  alert(res.snapshotLength == 1);

The requirement probably needs to be clarified. I would read it as
saying that you evaluate the expression pretending that text nodes
that have a preceding sibling that is a text node, and text nodes
that have the empty string as value, do not exist, leading to this:

  var doc = new DOMParser().parseFromString("<y/>", "text/xml");
  var tx1 = doc.createTextNode("");
  doc.documentElement.appendChild(tx1);
  var res = doc.evaluate("/*/text()", doc, null, 7, null);
  alert(res.snapshotLength == 0);

or if you read the text as applying only when there multiple nodes

  var doc = new DOMParser().parseFromString("<y/>", "text/xml");
  var tx1 = doc.createTextNode("");
  var tx2 = doc.createTextNode("bar");
  doc.documentElement.appendChild(tx1);
  doc.documentElement.appendChild(tx2);
  var res = doc.evaluate("/*/text()", doc, null, 7, null);
  alert(res.snapshotItem(0).nodeValue.length == 3);

Which quite clarly must be true but is false in Opera and Firefox.
Of course, if you pretend the nodes do not exist, then this fails:

  var doc = new DOMParser().parseFromString("<y/>", "text/xml");
  var tx1 = doc.createTextNode("abc");
  var tx2 = doc.createTextNode("def");
  doc.documentElement.appendChild(tx1);
  doc.documentElement.appendChild(tx2);
  var res = doc.evaluate("count(//text()[. = 'abcdef'])",
    doc, null, 1, null);
  alert(res.numberValue == 1);

which it does in Firefox but not in Opera. So it's a filter after
evaluation based on the XPath data model in Opera, while Firefox
treats "text()" as "text node" which is not what authors would ex-
pect. How about just fixing the bugs? Even got a test suite now.
-- 
Björn Höhrmann · mailto:bjoern@hoehrmann.de · http://bjoern.hoehrmann.de
Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de
25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/ 

Received on Monday, 12 September 2011 17:12:20 UTC