xml - Using XPath - How do I select/count immediate siblings? -
i trying compound immediate following siblings same values together. having trouble select immediate siblings.
input:
<rows> <row> <month>1</month> <start_date>15/04/2013</start_date> <rate_amount>10</rate_amount> <discount>-2</discount> </row> <row> <month>2</month> <start_date>15/05/2013</start_date> <rate_amount>10</rate_amount> <discount>-2</discount> </row> <row> <month>3</month> <start_date>15/06/2013</start_date> <rate_amount>10</rate_amount> <discount>-5</discount> </row> <row> <month>4</month> <start_date>15/07/2013</start_date> <rate_amount>10</rate_amount> <discount>-2</discount> </row> </rows>
expected output:
<ratelist> <rate> <noofmonths>2</noofmonths> <startdate>15/04/2013</startdate> <rateamount>10</rateamount> <discount>-2</discount> </rate> <rate> <noofmonths>1</noofmonths> <startdate>15/06/2013</startdate> <rateamount>10</rateamount> <discount>-5</discount> </rate> <rate> <noofmonths>1</noofmonths> <startdate>15/07/2013</startdate> <rateamount>10</rateamount> <discount>-2</discount> </rate> </ratelist>
and xsl:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <ratelist> <xsl:apply-templates/> </ratelist> </xsl:template> <xsl:template match="row"> <xsl:variable name="noofmonths" select=".|following-sibling::*[rate_amount=current()/rate_amount][discount=current()/discount]"/> <xsl:if test="not(preceding-sibling::*[rate_amount=current()/rate_amount][discount=current()/discount])"> <rate> <noofmonths> <xsl:value-of select="count($noofmonths)"/> </noofmonths> <startdate> <xsl:value-of select="start_date"/> </startdate> <rateamount> <xsl:value-of select="rate_amount"/> </rateamount> <discount> <xsl:value-of select="discount"/> </discount> </rate> </xsl:if> </xsl:template> </xsl:stylesheet>
and output getting:
<ratelist> <rate> <noofmonths>3</noofmonths> <startdate>15/04/2013</startdate> <rateamount>10</rateamount> <discount>-2</discount> </rate> <rate> <noofmonths>1</noofmonths> <startdate>15/06/2013</startdate> <rateamount>10</rateamount> <discount>-5</discount> </rate> </ratelist>
can help, please? how select/count immediate siblings?
thank you!
try (some explanation comment in xslt):
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <ratelist> <xsl:apply-templates select="*/row"/> </ratelist> </xsl:template> <xsl:template match="row"> <!--look preceding row has not same data (rate_amount , discount ) current. , generate id, here month concatenated '#'.--> <xsl:variable name="notsamedata" select="concat(preceding-sibling::row [not(rate_amount=current()/rate_amount , discount=current()/discount )][1]/month,'#')"/> <!--count following month has same data current , same preceding month not same data current--> <xsl:variable name="noofmonths" select="count(following-sibling::* [ rate_amount=preceding-sibling::*[1]/rate_amount , discount = preceding-sibling::*[1]/discount] [ concat(preceding-sibling::row [not(rate_amount=current()/rate_amount , discount=current()/discount )][1]/month,'#') = $notsamedata ]) +1 "/> <!--output rows don not have not direct (first) preceding 1 same data.--> <xsl:if test="not(preceding-sibling::row[1][rate_amount=current()/rate_amount][discount=current()/discount])"> <rate> <noofmonths> <xsl:value-of select="$noofmonths"/> </noofmonths> <startdate> <xsl:value-of select="start_date"/> </startdate> <rateamount> <xsl:value-of select="rate_amount"/> </rateamount> <discount> <xsl:value-of select="discount"/> </discount> </rate> </xsl:if> </xsl:template> </xsl:stylesheet>
which generate following output:
<?xml version="1.0"?> <ratelist> <rate> <noofmonths>2</noofmonths> <startdate>15/04/2013</startdate> <rateamount>10</rateamount> <discount>-2</discount> </rate> <rate> <noofmonths>1</noofmonths> <startdate>15/06/2013</startdate> <rateamount>10</rateamount> <discount>-5</discount> </rate> <rate> <noofmonths>1</noofmonths> <startdate>15/07/2013</startdate> <rateamount>10</rateamount> <discount>-2</discount> </rate> </ratelist>
comment: did not use xlt:key because favorite xlst processor xsltproc not support current() in xls:key statements.
Comments
Post a Comment