Reputation: 219
I have an XPath problem. I need a test condition for any <iframe>
that is included in a <part>
, but not any <iframe>
s that are included in a <chapter>
. Note that <chapter>
s are included in a <part>
.
XML:
<book>
<part id="p1">
<h1>Add a heading</h1>
<p>some text here</p>
<p>more text here</p>
<div>
<h2>Add another heading</h2>
<p>more text</p>
</div>
<div class="someDivision">
<div class="someOtherDivision">
<h2>Heading</h2>
<div class="sect">
<h2>Heading</h2>
<iframe>Add iframe content</iframe>
</div>
</div>
</div>
<chapter>
<h1>Add a chapter heading</h1>
<p>some chapter text here</p>
<div class="someDivision">
<div class="someOtherDivision">
<h2>Heading</h2>
<div class="sect">
<h2>Heading</h2>
<iframe>Add more iframe content</iframe>
</div>
</div>
</div>
</chapter>
</part>
<part id="p2">
<h1>Add a heading</h1>
<p>some text here</p>
<p>more text here</p>
<div>
<h2>Add another heading</h2>
<p>more text</p>
</div>
<chapter>
<h1>Add a chapter heading</h1>
<p>some chapter text here</p>
<div class="someDivision">
<div class="someOtherDivision">
<h2>Heading</h2>
<div class="sect">
<h2>Heading</h2>
<iframe>Add more iframe content</iframe>
</div>
</div>
</div>
</chapter>
</part>
</book>
XSLT:
<xsl:template match="/">
<xsl:element name="manifest">
<xsl:for-each select="//part">
<xsl:element name="item">
<xsl:attribute name="id" select="@id/string()"/>
<xsl:if test="//div[@class='someDivision']/div[@class='someOtherDivision']//iframe">
<xsl:attribute name="properties" select="'remote-resources'"/>
</xsl:if>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
I get this result:
<manifest>
<item id="p1" properties="remote-resources"/>
<item id="p2" properties="remote-resources"/>
</manifest>
But I only want:
<manifest>
<item id="p1" properties="remote-resources"/>
</manifest>
As there is no <iframe>
directly in <part>
and not nested within a <chapter>
. But I'm not sure how to accomplish this when my XPath will select any <iframe>
within a <part>
(which includes the ones in a <chapter>
.
Upvotes: 0
Views: 32
Reputation: 117073
I need to select any
<iframe>
that is included in a<part>
, but not any<iframe>
s that are included in a<chapter>
.
So how about:
/book/part//iframe[not(ancestor::chapter)]
If you want to test, from the context of a part
, if the current part
contains any iframe
elements that are not descendants of a chapter
, then do something like this:
<xsl:template match="/book">
<manifest>
<xsl:for-each select="part">
<item id="{@id}">
<xsl:if test=".//iframe[not(ancestor::chapter)]">
<!-- code if true -->
</xsl:if>
</item>
</xsl:for-each>
</manifest>
</xsl:template>
Demo: http://xsltransform.hikmatu.com/jyH9rLY
Upvotes: 1