Hi Guys,

I am new to XSLT, looking to solve a problem I am facing in filtering XML records.

I need to get both the Input XML record position and limit the output XML to a particular number (based on input provided to xsl:param from .net 1.1)

Input XML

<Parent>
<Child>AAA</Child>
<Child>ABA</Child>
<Child>DAA</Child>
<Child>DBAA</Child>
<Child>BZA</Child>
</Parent>

Output XML(Required)

<table>
<tr>
<td id="Row{Position of the record in Input XML}> node value </td>
</tr>
</table>

Eg: SearchParam='D' and Output Limit=1

if I am searching for one text starting with 'D', the output should be

<table>
<tr>
<td id="Row3>DAA</td>
</tr>
</table>

I am using XSLT:starts-with to get the records I need. But I am only able to limit the count or record position at any one point of time using the position() method.

Can anyone tell me how to achieve this,

Thanks,
Sarath

Dani AI

Generated

Brief answer: collect the matching Child nodes into a node-set, loop the first N matches (N comes from an xsl:param), and for each matched node compute its original index with count(preceding-sibling::Child)+1. This avoids relying on position() (which is relative to the current node-set) and generalizes 's "first match" trick so you can return any output limit requested by .

Example (XSLT 1.0 sketch):

<xsl:param name="search" select="'D'"/>
<xsl:param name="limit" select="1"/>
<xsl:variable name="len" select="string-length($search)"/>
<xsl:variable name="matches" select="/Parent/Child[substring(.,1,$len) = $search]"/>

<xsl:for-each select="$matches[position() &lt;= $limit]">
  <tr>
    <td id="{concat('Row', count(preceding-sibling::Child) + 1)}">
      <xsl:value-of select="."/>
    </td>
  </tr>
</xsl:for-each>

Notes and caveats:

  • Use substring(.,1,$len) = $search because XSLT 1.0 has no starts-with().
  • position() inside the for-each refers to the rank within the filtered $matches; the original position in the input is count(preceding-sibling::Child)+1.
  • If Child text may include extra whitespace, use normalize-space(.) in the match test. If there are multiple Parent elements, scope /Parent accordingly.
  • For large documents or many repeated queries, the substring test is linear; consider indexing or moving to XSLT 2.0 if available.

Passing params: declare the xsl:param names in the stylesheet and supply values from your host (your .NET caller) so the stylesheet uses the runtime search string and limit.

This extends 's approach (which is ideal for a single first match) into a reusable pattern that returns the first N matches and reports each match's original input position.

Recommended Answers

All 2 Replies

I use param to the outside to control xslt

The first parameter indicates the length of a string
The second parameter is the string being searched

by specifying

and not (preceding-sibling:: Child [substring (.,1,$length) = $alpha]

only the first matching child node appears

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output indent="yes" method="html"/>
	<xsl:param name="length" select="1"/>
	<xsl:param name="alpha" select="'B'"/>
	<xsl:template match="/">
		<html>
			<body>
				<xsl:apply-templates select="Parent"/>
			</body>
		</html>
	</xsl:template>
	<xsl:template match="Parent">
		<table>
			<xsl:apply-templates select="Child"/>
		</table>
	</xsl:template>

	<xsl:template match="Child">
		<xsl:if test="(substring(.,1,$length) = $alpha) and not(preceding-sibling::Child[substring(.,1,$length) = $alpha])">
			<tr>
				<td id="Row{position()}">
					<xsl:value-of select="."/>
				</td>
			</tr>
		</xsl:if>
	</xsl:template>
</xsl:stylesheet>

result param1=1 param2='B'

<html>
  <body>
    <table>
      <tr>
        <td id="Row5">BZA</td>
      </tr>
    </table>
  </body>
</html>

hello...
my name is Maruli Situmorang
I want to ask the all master of java
how transform pdf file to xml in java
thank a lot

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.