Here is a simple XSLT 1.0 solution:
<xsl:stylesheet version="1.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[text()[contains(., 'abc')]]">
<xsl:value-of select="text()[contains(., 'abc')]"/>
<xsl:value-of select="'
'"/>
<xsl:apply-templates select="." mode="genPath"/>
</xsl:template>
<xsl:template match="text()"/>
<xsl:variable name="vApos">'</xsl:variable>
<xsl:template match="*[@* or not(*)]" mode="genPath">
<xsl:if test="not(*)">
<xsl:apply-templates select="ancestor-or-self::*" mode="path"/>
<xsl:value-of select="concat('=',$vApos,.,$vApos)"/>
<xsl:text>
</xsl:text>
</xsl:if>
<xsl:apply-templates select="@*|*"/>
</xsl:template>
<xsl:template match="*" mode="path">
<xsl:value-of select="concat('/',name())"/>
<xsl:variable name="vnumPrecSiblings" select=
"count(preceding-sibling::*[name()=name(current())])"/>
<xsl:if test="$vnumPrecSiblings">
<xsl:value-of select="concat('[', $vnumPrecSiblings +1, ']')"/>
</xsl:if>
</xsl:template>
<xsl:template match="@*">
<xsl:apply-templates select="../ancestor-or-self::*" mode="path"/>
<xsl:value-of select="concat('[@',name(), '=',$vApos,.,$vApos,']')"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<Test>
<Context1>
<ItemA>abc - yes!</ItemA>
<ItemB>def</ItemB>
</Context1>
<Context2>
<ItemC>ghi</ItemC>
<Context3>
<ItemD>abc ... oky-dokey</ItemD>
<ItemE>jkl</ItemE>
</Context3>
</Context2>
<Context4>
<ItemF>mno</ItemF>
</Context4>
</Test>
The wanted, correct result is produced:
abc - yes!
/Test/Context1/ItemA='abc - yes!'
abc ... oky-dokey
/Test/Context2/Context3/ItemD='abc ... oky-dokey'
For explanation of the path-generation, see this:
https://stackoverflow.com/questions/4746299/generate-get-xpath-from-xml-node-java/4747858#4747858Thanks,
Dimitre