Issue with XSL Criteria
- by Rachel
I am using the below piece of XSL to select the id of the text nodes whose content has a given index. This index value in input will be relative to a spcified node whose id value is known. The criteria to select the text node is,
The text node content should contain a index say 'i' relative to node say 'n' whose id value i know.
'i' and 'id of n' is got as index and nodeName from the input param as seen in the xsl.
Node 'd1e5' has the text content whose index ranges from 1 to 33. When i give an index value greater than 33 i want the below criteria to fail but it does not,
[sum((preceding::text(), .)[normalize-space()][. >> //*[@id=$nodeName]]/string-length(.)) ge $index]
Input xml:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" id="d1e1">
<head id="d1e3">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title id="d1e5">Every document must have a title</title>
</head>
<body id="d1e9">
<h1 id="d1e11" align="center">Very Important Heading</h1>
<p id="d1e13">Since this is just a sample, I won't put much text here.</p>
</body>
</html>
XSL code used:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xsd"
version="2.0">
<xsl:param name="insert-file" as="node()+">
<insert-data><data index="1" nodeName="d1e5"></data><data index="34" nodeName="d1e5"></data></insert-data>
</xsl:param>
<xsl:param name="nodeName" as="xsd:string" />
<xsl:variable name="main-root" as="document-node()" select="/"/>
<xsl:variable name="insert-data" as="element(data)*">
<xsl:for-each select="$insert-file/insert-data/data">
<xsl:sort select="xsd:integer(@index)"/>
<xsl:variable name="index" select="xsd:integer(@index)" />
<xsl:variable name="nodeName" select="@nodeName" />
<data text-id="{generate-id($main-root/descendant::text()[sum((preceding::text(), .)[normalize-space()][. >> //*[@id=$nodeName]]/string-length(.)) ge $index][1])}">
</data>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<Output>
<xsl:copy-of select="$insert-data" />
</Output>
</xsl:template>
</xsl:stylesheet>
Actual output:
<?xml version="1.0" encoding="UTF-8"?>
<Output>
<data text-id="d1t8"/>
<data text-id="d1t14"/>
</Output>
Expected output:
<?xml version="1.0" encoding="UTF-8"?>
<Output>
<data text-id="d1t8"/>
</Output>
This solution works fine if index lies between 1 and 33. Any index value greater that 33 causes incorrect text nodes to get selected. I could not understand why the text node 'd1t14' is getting selected.
Please share your thoughts.