Here's a clean XPath 2.0 expression, admittedly not for the faint of heart :
(for $m in max(for $n in distinct-values(/*/b:book/(b:author | b:editor) /b:name/concat(b:fname, '|', b:lname)), $cnt in count(/*/b:book/(b:author | b:editor) /b:name[$n eq concat(b:fname, '|', b:lname) ]) return $cnt ), $name in /*/b:book/(b:author | b:editor)/b:name, $fullName in $name/concat(b:fname, '|', b:lname), $count in count( /*/b:book/(b:author | b:editor) /b:name[$fullName eq concat(b:fname, '|', b:lname)]) return if($count eq $m) then $name else () )[1]
where the prefix "b:" is associated with the namespace "books" .
XSLT 2.0 based validation :
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:b="books"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="/"> <xsl:sequence select= "(for $m in max(for $n in distinct-values(/*/b:book/(b:author | b:editor) /b:name/concat(b:fname, '|', b:lname)), $cnt in count(/*/b:book/(b:author | b:editor) /b:name[$n eq concat(b:fname, '|', b:lname) ]) return $cnt ), $name in /*/b:book/(b:author | b:editor)/b:name, $fullName in $name/concat(b:fname, '|', b:lname), $count in count( /*/b:book/(b:author | b:editor) /b:name[$fullName eq concat(b:fname, '|', b:lname)]) return if($count eq $m) then $name else () )[1] "/> </xsl:template> </xsl:stylesheet>
when this conversion is applied to the provided XML document :
<books xmlns="books"> <book ISBN="i0321165810" publishername="OReilly"> <title>XPath</title> <author> <name> <fname>Priscilla</fname> <lname>Walmsley</lname> </name> </author> <year>2007</year> <field>Databases</field> </book> <book ISBN="i0321165812" publishername="OReilly"> <title>XQuery</title> <author> <name> <fname>Priscilla</fname> <lname>Walmsley</lname> </name> </author> <editor> <name> <fname>Lisa</fname> <lname>Williams</lname> </name> </editor> <year>2003</year> <field>Databases</field> </book> <publisher publishername="OReilly"> <web-site>www.oreilly.com</web-site> <address> <street_address>hill park</street_address> <zip>90210</zip> <state>california</state> </address> <phone>400400400</phone> <e-mail> oreilly@oreilly.com </e-mail> <contact> <field>Databases</field> <name> <fname>Anna</fname> <lname>Smith</lname> </name> </contact> </publisher> </books>
the desired, correct name element is selected and displayed :
<name xmlns="books"> <fname>Priscilla</fname> <lname>Walmsley</lname> </name>