As bambax noted in his answer, the XSLT key solution is more efficient , especially for large XML documents:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes"/> <xsl:key name="kAuthByTitle" match="attribute[@name='Author']" use="preceding-sibling::attribute[@name='Title'][1]"/> <xsl:template match="/"> Book C Author: <xsl:copy-of select= "key('kAuthByTitle', 'Book C')"/> ==================== Book B Author: <xsl:copy-of select= "key('kAuthByTitle', 'Book B')"/> </xsl:template> </xsl:stylesheet>
When the above conversion is applied to this XML document:
<t> <attribute name="Title">Book A</attribute> <attribute name="Code">1</attribute> <attribute name="Author"> <value>James Berry</value> <value>John Smith</value> </attribute> <attribute name="Title">Book B</attribute> <attribute name="Code">2</attribute> <attribute name="Title">Book C</attribute> <attribute name="Code">3</attribute> <attribute name="Author"> <value>James Berry</value> </attribute> </t>
the correct output is created:
Book C Author: <attribute name="Author"> <value>James Berry</value> </attribute> ==================== Book B Author:
Note that you should avoid abbreviation of the abbreviation "//" XPath as much as possible , as this usually causes the entire XML document to be scanned with every evaluation of the XPath expression.
source share