Reputation: 1020
I have xml like follows,
<doc>
<meta-data>
<paper-name>ABC</paper-name>
<paper-type>fi</paper-type>
</meta-data>
<section>
<figure>fig1</figure>
<figure>fig2</figure>
</section>
</doc>
My requirement is, if <paper-type>
node is available in <meta-data>
change <figure>
nodes to <image>
node.
So, output should look like,
<doc>
<meta-data>
<paper-name>ABC</paper-name>
<paper-type>fi</paper-type>
</meta-data>
<section>
<image>fig1</image>
<image>fig2</image>
</section>
</doc>
I have written following xsl to do this task,
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:function name="abc:check-paper-type" as="xs:boolean">
<xsl:sequence select="root()//meta-data/paper-type"/>
</xsl:function>
<xsl:template match="figure[abc:check-paper-type()]">
<image>
<xsl:apply-templates/>
</image>
</xsl:template>
to check <paper-type>
node is available inside <meta-data>
I have written a function here named 'check-paper-type'. but is does not work as expected.
Any suggestion how can I organize my function to check, <paper-type>
is available or not?
Note that, I need to change lots of node by checking <paper-type>
node exist or not. So, It'll be important to check <paper-type>
exist or not by using a function.
Upvotes: 0
Views: 90
Reputation: 117102
The reason why your attempt cannot work is this:
Within the body of a stylesheet function, the focus is initially undefined; this means that any attempt to reference the context item, context position, or context size is a non-recoverable dynamic error. [XPDY0002]
http://www.w3.org/TR/xslt20/#stylesheet-functions
You could do simply:
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="figure[../../meta-data/paper-type]">
<image>
<xsl:apply-templates select="@*|node()"/>
</image>
</xsl:template>
Given your input, this will produce:
<?xml version="1.0" encoding="UTF-8"?>
<doc>
<meta-data>
<paper-name>ABC</paper-name>
<paper-type>fi</paper-type>
</meta-data>
<section>
<image>fig1</image>
<image>fig2</image>
</section>
</doc>
Alternatively, if you need to refer to the existence of the node repeatedly, you can define it as a variable, instead of a function:
<xsl:variable name="check-paper-type" select="exists(/doc/meta-data/paper-type)" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="figure[$check-paper-type]">
<image>
<xsl:apply-templates select="@*|node()"/>
</image>
</xsl:template>
Upvotes: 1