Reputation: 1421
Suppose the following xhtml
...
<a>
skipcontent_1
<div>
skipcontent_2
</div>
<div id='info'>
showcontent_3
<div>
showcontent_4
</div>
<c>
skipcontent_5
</c>
</div>
</a>
...
I would like to have only the text from those div
elements, which have id='info'
or are below of such a div
So the result should look like this
showcontent_3
showcontent_4
(ident/newlines are not important)
I tried hard to have an identity transformation acting like this, but already failed by letting it ignore the nodes/content "outside" of a <div id='info'/>
section...
Upvotes: 0
Views: 198
Reputation: 190
It sounds to me like your problem is a better fit for a stylesheet without an identity template. This stylesheet satisfies your requirements given that input:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="text()" priority="1">
<!-- Do not output text normally -->
</xsl:template>
<xsl:template match="div/text()[ancestor::div[@id = 'info']]" priority="2">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
To deconstruct a bit:
Generally, you want to output nothing. That's the reason for the first template, since default behavior in XSLT for a text node is to copy it to output.
You do want certain text nodes to be copied to output, so the second template handles those. The match expression finds text nodes that satisfy two things: (1) that they are a text node that is a child of a div
element (div/text()
) and (2) that they are somewhere beneath a div
element that has the @id
attribute set to "info" ([ancestor::div[@id = 'info']]
).
(The second template's match expression could be (more or less) equivalently written as div[@id = 'info']//text()[parent::div]
.)
Upvotes: 2