This answer uses only XPath 1.0 expressions. My understanding is that XPath 2.0 isn't available.
Use:
//div[contains(@id, 'Content') or contains(@class, 'Content')]
[not(descendant::div[contains(@id, 'Content') or contains(@class, 'Content')])]
This selects any div
element whose id
attribute has string value that contains the string "content"
, or whose class
attribute has string value that contains the string "content"
, and that has no descendant div
elements with this properties.
Do note, that such thing as "the most inner div" may not be singular -- that is, many div
elements may exist such that they fulfill the conditions set in the question.
If this is the case, and you need just one such div
element (say, the 1st), you can use:
(//div[contains(@id, 'content') or contains(@class, 'content')]
[not(descendant::div[contains(@id, 'content') or contains(@class, 'content')])]
)[1]
XSLT - based verification:
<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="/">
<xsl:copy-of select=
"//div[contains(@id, 'Content') or contains(@class, 'Content')]
[not(descendant::div[contains(@id, 'Content') or contains(@class, 'Content')])]"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the first provided XML document:
<body>
<div class="outerContent">
<div id="moreContent">
<div class="anotherContent">
This is what I am looking for.
</div>
</div>
</div>
</body>
the Xpath expression is evaluated and the result of this evaluation is copied to the output:
<div class="anotherContent">
This is what I am looking for.
</div>
With the second document, again the correct result is produced:
<div id="anotherContent">
This is what I am looking for.
</div>
Finally, in case the comparisson for "Content" should be case-independet, use:
//div[contains(translate(@id,'CONTE','conte'), 'content')
or contains(translate(@class,'CONTE','conte'), 'content')
]
[not(descendant::div
[contains(translate(@id,'CONTE','conte'), 'content')
or contains(translate(@class,'CONTE','conte'), 'content')
]
)
]