At 03:38 PM 3/10/2003, Markus wrote:
Robert P. J. Day wrote:
if i want to select all elements that have at least one, say,
"book" child element, it seems i can do it this way:
//*[name(child::*) = "book"] long way
//*[name(*) = "book"] shorter way
1) is this the easiest way to do it?
//*[book]
2) why doesn't the following work as well?
//*[name(node()) = "book"]
i'm not sure, but i think this will compare the name of the first child only.
Yup. The name() function takes a node set as its argument, and returns the
name of the first node in the node set.
All three of Robert's name tests will fall into this category.
//*[book] is the way to do it, since the XPath expression "book" (short for
child::book) returns true if there are any book child elements (not just if
the first element child is a book)
//*[book] is short for
/descendant-or-self::node()/child::*[child::book]
(Traversing from the root, get all nodes at any depth, then get any element
child that has a book element child.)
name(node())='book' might be seeming to fail where name(*)='book' seems to
work due to whitespace in the input. If the first element child is a <book>
but it is preceded by a text node (even one that just contains a line
feed), the test name(node())='book' on its parent will test false whereas
name(*)='book' tests true.
I hope this clarifies!
Wendell
======================================================================
Wendell Piez
mailto:wapiez(_at_)mulberrytech(_dot_)com
Mulberry Technologies, Inc. http://www.mulberrytech.com
17 West Jefferson Street Direct Phone: 301/315-9635
Suite 207 Phone: 301/315-9631
Rockville, MD 20850 Fax: 301/315-8285
----------------------------------------------------------------------
Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list