Reputation: 17335
This is my XML file:
<root>
<?pistart ?>
<elt>
<?pistop ?>
</elt>
</root>
Now (using XPath 2.0) I'd like to know if there is only text between the processing instruction pistart
and the next processing instruction pistop
. The answer above would be 'no, there is an start element tag'.
A pistart
can never occur after another pistart
without a corresponding pistop
. Thus this is not possible (if it helps to solve my problem):
<root>
<?pistart ?>
<elt>
<?pistart ?>
<?pistop ?>
</elt>
<?pistop ?>
</root>
Upvotes: 1
Views: 186
Reputation: 243459
Use this XPath 1.0 expression(which, of course, is also an XPath 2.0 one)
Assuming the pistart is the context item:
boolean(following::node()[not(self::text())][1][self::processing-instruction('pistop')])
Upvotes: 1
Reputation: 163262
Perhaps (assuming the pistart is the context item):
exists(following-sibling::node()[1][self::text()]
/following-sibling::node()[1][self::processing-instruction(pistop))
Upvotes: 1
Reputation: 167401
Based on the suggestion in my comment, I think
<xsl:template match="/">
<xsl:for-each-group select="/root//node()"
group-starting-with="processing-instruction('pistart')">
<xsl:if test="self::processing-instruction('pistart')">
<xsl:variable name="end" select="current-group()[self::processing-instruction('pistop')]"/>
<xsl:value-of
select="
every $group-member in current-group()[position() gt 1 and . << $end]
satisfies $group-member instance of text()"
/>
</xsl:if>
</xsl:for-each-group>
</xsl:template>
will do to output true
for any group of pi pairs satisfying the condition and false for those not satisfying it.
It might be easier to nest an additional for-each-group group-ending-with="processing-instruction('pistop')"
to grab the nodes to check.
Upvotes: 1