I need help with merging several tables of one file into one output.
The files that I get processed perfectly according to the XSLT schema that is listed below. But today I received an interesting file that was not processed as I wanted.
source file
<?xml version="1.0" encoding="utf-8"?>
<extdata user="test">
<scheme name="Order">
<data>
<s>
<d name="CashOrder">
<f name="ActionDate" type="Date" />
<f name="AddressId" type="String" />
<f name="CompanyId" type="String" />
</d>
</s>
<o>
<d name="CashOrder">
<r>
<f>2022-01-24T00:00:00</f>
<f>10234</f>
<f>10234</f>
</r>
<r>
<f>2022-01-24T00:00:00</f>
<f>52817</f>
<f>52817</f>
</r>
<r>
<f>2022-01-24T00:00:00</f>
<f>58259</f>
<f>58259</f>
</r>
</d>
</o>
</data>
<data>
<s>
<d name="OrderOption">
<f name="OrderDate" type="Date" />
<f name="OrderNumber" type="String" />
</d>
</s>
<o>
<d name="OrderOption">
<r>
<f>2022-01-24T00:00:00</f>
<f>WE30395.c17639</f>
</r>
<r>
<f>2022-01-24T00:00:00</f>
<f>WE30395.c17639</f>
</r>
<r>
<f>2022-01-24T00:00:00</f>
<f>WE30395.c17639</f>
</r>
</d>
</o>
</data>
</scheme>
</extdata>
my XSLT (here they helped me with writing.there was a problem with the recursive processing of the hierarchy)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/extdata/scheme">
<ValueTable xmlns="http://v8.1c.ru/8.1/data/core" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:for-each select="data/s/d/f | data/s/d/d/f">
<column>
<Name xsi:type="xs:string">
<xsl:value-of select="#name" />
</Name>
<ValueType>
<xsl:if test="#type= 'String'">
<Type>xs:string</Type>
<StringQualifiers>
<Length>150</Length>
<AllowedLength>Variable</AllowedLength>
</StringQualifiers>
</xsl:if>
<xsl:if test="#type= 'Date'">
<Type>xs:dateTime</Type>
<DateQualifiers>
<DateFractions>DateTime</DateFractions>
</DateQualifiers>
</xsl:if>
<xsl:if test="#type= 'Decimal' or #type= 'Currency'">
<Type>xs:decimal</Type>
<NumberQualifiers>
<Digits>20</Digits>
<FractionDigits>4</FractionDigits>
<AllowedSign>Any</AllowedSign>
</NumberQualifiers>
</xsl:if>
<xsl:if test="#type= 'Integer'">
<Type>xs:decimal</Type>
<NumberQualifiers>
<Digits>20</Digits>
<FractionDigits>0</FractionDigits>
<AllowedSign>Any</AllowedSign>
</NumberQualifiers>
</xsl:if>
</ValueType>
</column>
</xsl:for-each>
<xsl:for-each select="data/o/d/r">
<row>
<xsl:for-each select=".//f">
<Value>
<xsl:value-of select="." />
</Value>
</xsl:for-each>
</row>
</xsl:for-each>
</ValueTable>
</xsl:template>
</xsl:stylesheet>
output now
<ValueTable xmlns="http://v8.1c.ru/8.1/data/core"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<column>
<Name xsi:type="xs:string">ActionDate</Name>
<ValueType>
<Type>xs:dateTime</Type>
<DateQualifiers>
<DateFractions>DateTime</DateFractions>
</DateQualifiers>
</ValueType>
</column>
<column>
<Name xsi:type="xs:string">AddressId</Name>
<ValueType>
<Type>xs:string</Type>
<StringQualifiers>
<Length>150</Length>
<AllowedLength>Variable</AllowedLength>
</StringQualifiers>
</ValueType>
</column>
<column>
<Name xsi:type="xs:string">CompanyId</Name>
<ValueType>
<Type>xs:string</Type>
<StringQualifiers>
<Length>150</Length>
<AllowedLength>Variable</AllowedLength>
</StringQualifiers>
</ValueType>
</column>
<column>
<Name xsi:type="xs:string">OrderDate</Name>
<ValueType>
<Type>xs:dateTime</Type>
<DateQualifiers>
<DateFractions>DateTime</DateFractions>
</DateQualifiers>
</ValueType>
</column>
<column>
<Name xsi:type="xs:string">OrderNumber</Name>
<ValueType>
<Type>xs:string</Type>
<StringQualifiers>
<Length>150</Length>
<AllowedLength>Variable</AllowedLength>
</StringQualifiers>
</ValueType>
</column>
<row>
<Value>2022-01-24T00:00:00</Value>
<Value>10234</Value>
<Value>10234</Value>
</row>
<row>
<Value>2022-01-24T00:00:00</Value>
<Value>52817</Value>
<Value>52817</Value>
</row>
<row>
<Value>2022-01-24T00:00:00</Value>
<Value>58259</Value>
<Value>58259</Value>
</row>
<row>
<Value>2022-01-24T00:00:00</Value>
<Value>WE30395.c17639</Value>
</row>
<row>
<Value>2022-01-24T00:00:00</Value>
<Value>WE30395.c17639</Value>
</row>
<row>
<Value>2022-01-24T00:00:00</Value>
<Value>WE30395.c17639</Value>
</row>
</ValueTable>
need
<ValueTable xmlns="http://v8.1c.ru/8.1/data/core"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<column>
<Name xsi:type="xs:string">ActionDate</Name>
<ValueType>
<Type>xs:dateTime</Type>
<DateQualifiers>
<DateFractions>DateTime</DateFractions>
</DateQualifiers>
</ValueType>
</column>
<column>
<Name xsi:type="xs:string">AddressId</Name>
<ValueType>
<Type>xs:string</Type>
<StringQualifiers>
<Length>150</Length>
<AllowedLength>Variable</AllowedLength>
</StringQualifiers>
</ValueType>
</column>
<column>
<Name xsi:type="xs:string">CompanyId</Name>
<ValueType>
<Type>xs:string</Type>
<StringQualifiers>
<Length>150</Length>
<AllowedLength>Variable</AllowedLength>
</StringQualifiers>
</ValueType>
</column>
<column>
<Name xsi:type="xs:string">OrderDate</Name>
<ValueType>
<Type>xs:dateTime</Type>
<DateQualifiers>
<DateFractions>DateTime</DateFractions>
</DateQualifiers>
</ValueType>
</column>
<column>
<Name xsi:type="xs:string">OrderNumber</Name>
<ValueType>
<Type>xs:string</Type>
<StringQualifiers>
<Length>150</Length>
<AllowedLength>Variable</AllowedLength>
</StringQualifiers>
</ValueType>
</column>
<row>
<Value>2022-01-24T00:00:00</Value>
<Value>10234</Value>
<Value>10234</Value>
<Value>2022-01-24T00:00:00</Value>
<Value>WE30395.c17639</Value>
</row>
<row>
<Value>2022-01-24T00:00:00</Value>
<Value>52817</Value>
<Value>52817</Value>
<Value>2022-01-24T00:00:00</Value>
<Value>WE30395.c17639</Value>
</row>
<row>
<Value>2022-01-24T00:00:00</Value>
<Value>58259</Value>
<Value>58259</Value>
<Value>2022-01-24T00:00:00</Value>
<Value>WE30395.c17639</Value>
</row>
</ValueTable>
Briefly, the structure can be described as follows
I mean this is how I got it
<table>
<header>
<column1>
<column2>
<column3>
<column4>
<column5>
<header>
<row>
value1
value2
value3
</row>
<row>
value4
value5
</row>
</table>
but it should be like this
<table>
<header>
<column1>
<column2>
<column3>
<column4>
<column5>
</header>
<row>
value1
value2
value3
value4
value5
</row>
</table>
The example is rather confusing because many values are identical and it's hard to see what goes where. It's also not clear if there can be more data elements and if so, what should the result be then.
AFAICT, this produces the expected result for the given example. For clarity, I have omitted the header part, which seems to be working fine.
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" indent="yes" />
<xsl:template match="/extdata/scheme">
<ValueTable xmlns="http://v8.1c.ru/8.1/data/core" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- header -->
<!-- data -->
<xsl:for-each select="data[1]/o/d/r">
<row>
<xsl:variable name="i" select="position()"/>
<xsl:for-each select="//data/o/d/r[$i]/f">
<Value>
<xsl:value-of select="." />
</Value>
</xsl:for-each>
</row>
</xsl:for-each>
</ValueTable>
</xsl:template>
</xsl:stylesheet>
In the below XML, I need to sort only a specific segment - attrGroupMany name="allergenRelatedInformation" based on the grand child values. And the rest of the XML should be generated as it is with just this segment sorted.
FDA
BIG 8
So all allergenSpecificationAgency that has "FDA" and allergenSpecificationName has "BIG 8" should come before "FDA" and "TREE_NUTS". Please suggest how to achieve this in XSLT. Thanks.
<ns:MT_TradeItemsExport xmlns:ns="test">
<Header version="2.1">
<CreationDateTime>2017-02-09T14:19:03.566Z</CreationDateTime>
<MessageID>0072745000010_9f9cd85e-6d30-4152-a51f-d8491df45486</MessageID>
</Header>
<Payload>
<ItemRegistration>
<attr name="numberOfServingsPerPackage">4.0</attr>
</ItemRegistration>
<attrGroupMany name="organicClaim">
<row>
<attr name="organicTradeItemCode">2</attr>
<attrMany name="organicClaimAgencyCode">
<value>6</value>
</attrMany>
</row>
</attrGroupMany>
<attrGroupMany name="allergenRelatedInformation">
<row>
<attr name="allergenSpecificationAgency">FDA</attr>
<attr name="allergenSpecificationName">BIG 8</attr>
<attrGroupMany name="allergen">
<row>
<attr name="allergenTypeCode">AC</attr>
<attr name="levelOfContainmentCode">FREE_FROM</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="allergenSpecificationAgency">FDA</attr>
<attr name="allergenSpecificationName">BIG 8</attr>
<attrGroupMany name="allergen">
<row>
<attr name="allergenTypeCode">AE</attr>
<attr name="levelOfContainmentCode">FREE_FROM</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="allergenSpecificationAgency">FDA</attr>
<attr name="allergenSpecificationName">BIG 8</attr>
<attrGroupMany name="allergen">
<row>
<attr name="allergenTypeCode">AF</attr>
<attr name="levelOfContainmentCode">FREE_FROM</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="allergenSpecificationAgency">FDA</attr>
<attr name="allergenSpecificationName">BIG 8</attr>
<attrGroupMany name="allergen">
<row>
<attr name="allergenTypeCode">AM</attr>
<attr name="levelOfContainmentCode">FREE_FROM</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="allergenSpecificationAgency">FDA</attr>
<attr name="allergenSpecificationName">BIG 8</attr>
<attrGroupMany name="allergen">
<row>
<attr name="allergenTypeCode">AN</attr>
<attr name="levelOfContainmentCode">FREE_FROM</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="allergenSpecificationAgency">FDA</attr>
<attr name="allergenSpecificationName">BIG 8</attr>
<attrGroupMany name="allergen">
<row>
<attr name="allergenTypeCode">AP</attr>
<attr name="levelOfContainmentCode">FREE_FROM</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="allergenSpecificationAgency">FDA</attr>
<attr name="allergenSpecificationName">BIG 8</attr>
<attrGroupMany name="allergen">
<row>
<attr name="allergenTypeCode">AY</attr>
<attr name="levelOfContainmentCode">FREE_FROM</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="allergenSpecificationAgency">FDA</attr>
<attr name="allergenSpecificationName">TREE_NUTS</attr>
<attrGroupMany name="allergen">
<row>
<attr name="allergenTypeCode">TN</attr>
<attr name="levelOfContainmentCode">FREE_FROM</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="allergenSpecificationAgency">FDA</attr>
<attr name="allergenSpecificationName">BIG 8</attr>
<attrGroupMany name="allergen">
<row>
<attr name="allergenTypeCode">UW</attr>
<attr name="levelOfContainmentCode">FREE_FROM</attr>
</row>
</attrGroupMany>
</row>
</attrGroupMany>
</Payload>
You can use xsl:perform-sort or xsl:apply-templates together with xsl:sort, to sort the row children use
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="attrGroupMany[#name ='allergenRelatedInformation']">
<xsl:copy>
<xsl:apply-templates select="#*"/>
<xsl:apply-templates select="row">
<xsl:sort select="attr[#name = 'allergenSpecificationAgency']"/>
<xsl:sort select="attr[#name = 'allergenSpecificationName']"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:transform>
http://xsltransform.net/ejivdHR
I have a Table it has two column.
Based on First column's rowmerge and rowspan attribute it should merge the values of next column.
RowMerged attribute is to find out whether cells are merged.
RowSpan attribute is to find-out how many cells are merged.
If Rowspan is 0 then that cells is merged with above one.
In the below example we give input as 5 Rows and it will return 3 row as output.
ie) First two rows are merged into single and the content of second column which is not merged should be copied to the above one.
Concerned main on content of cell not the attribute.
Sample Input:
<Table Name="abc">
<TBODY>
<Row>
<Cell RowMerged="T" RowSpan="2"><Element>ABC</Element></Cell>
<Cell><Element>21</Element></Cell>
</Row>
<Row>
<Cell RowMerged="T" RowSpan="0"></Cell>
<Cell><Element>ABC</Element></Cell>
</Row>
<Row>
<Cell RowMerged="F" RowSpan="1"><Element>PQR</Element></Cell>
<Cell><Element>19</Element></Cell>
</Row>
<Row>
<Cell RowMerged="T" RowSpan="2"><Element>XYZ</Element></Cell>
<Cell><Element>99</Element></Cell>
</Row>
<Row>
<Cell RowMerged="T" RowSpan="0"></Cell>
<Cell><Element>Sample</Element></Cell>
</Row>
</TBODY>
</Table>
Sample Output:
<Table Name="abc">
<TBODY>
<Row>
<Cell RowMerged="F" RowSpan="1"><Element>ABC</Element></Cell>
<Cell><Element>21ABC</Element></Cell>
</Row>
<Row>
<Cell RowMerged="F" RowSpan="1"><Element>PQR</Element></Cell>
<Cell><Element>19</Element></Cell>
</Row>
<Row>
<Cell RowMerged="F" RowSpan="1"><Element>XYZ</Element></Cell>
<Cell><Element>99Sample</Element></Cell>
</Row>
</TBODY>
</Table>
You may try something like this:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Row">
<xsl:variable name="rows" select="Cell[1]/#RowSpan"/>
<xsl:copy>
<Cell RowMerged="F" RowSpan="1">
<xsl:apply-templates select="Cell[1]/*" />
</Cell>
<Cell>
<Element>
<xsl:apply-templates select="Cell[2]/Element/node()" />
<xsl:apply-templates select="following-sibling::Row[position() < $rows]/Cell[2]/Element/node()" />
</Element>
</Cell>
</xsl:copy>
<xsl:apply-templates select="Row[Cell[1][#RowSpan > 0]]" />
</xsl:template>
<xsl:template match="TBODY">
<xsl:apply-templates select="Row[Cell[1][#RowSpan > 0]]" />
</xsl:template>
</xsl:stylesheet>
With following output:
<Table Name="abc">
<Row>
<Cell RowMerged="F" RowSpan="1">
<Element>ABC</Element>
</Cell>
<Cell>
<Element>21ABC</Element>
</Cell>
</Row>
<Row>
<Cell RowMerged="F" RowSpan="1">
<Element>PQR</Element>
</Cell>
<Cell>
<Element>19</Element>
</Cell>
</Row>
<Row>
<Cell RowMerged="F" RowSpan="1">
<Element>XYZ</Element>
</Cell>
<Cell>
<Element>99Sample</Element>
</Cell>
</Row>
</Table>
We have two diffrent scenario we got answers in the forum
Xslt for table content replacement only in Tbody
(We need to retrieve ref tag inside para in Thead We need to remove ref tag inside para in Tbody. For last cell we should not perform this ref removal. ie) should behave like thead)
writing xslt for the below scenario
(Rule: for merged rows: copy content of primary merged cell to other cells in merged rows.)
But while integrating/testing we have a problem. after integrating we are not getting the expected output.ie) Tag removel is done on the first row but in the merged row it is noit heppening.
Could someone help us in this regard.
Sample Input:
<?xml version="1.0" encoding="UTF-8"?>
<TABLE align="CENTER" >
<THEAD editable="T">
<ROW editable="F">
<CELL rowmerged="F" ><Para appdisplaytext=" ">S.No </Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Name</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Role</Para></CELL>
<CELL colmerged="F" ><Para appdisplaytext=" " >Comment</Para></CELL>
</ROW>
</THEAD>
<TBODY editable="T">
<ROW editable="F">
<CELL rowmerged="T" ><Para appdisplaytext=" "><refint>S.No1 </refint> </Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Name1</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" "> <refint>Role1</refint></Para></CELL>
<CELL colmerged="F" ><Para appdisplaytext=" " >Comment1</Para> </CELL>
</ROW>
<ROW editable="F">
<CELL rowmerged="T" ><Para appdisplaytext=" "></Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Name2</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Role2</Para></CELL>
<CELL colmerged="F" ><Para appdisplaytext=" " >Comment2</Para> </CELL>
</ROW>
<ROW editable="F">
<CELL rowmerged="F" ><Para appdisplaytext=" ">S.No 3</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Name3</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" "><refint>Role3</refint></Para></CELL>
<CELL colmerged="F" ><Para appdisplaytext=" " >Comment3</Para></CELL>
</ROW>
<ROW editable="F">
<CELL rowmerged="F" ><Para appdisplaytext=" ">S.No 4</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Name4</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Role4</Para></CELL>
<CELL colmerged="F" ><Para appdisplaytext=" " >Comment4</Para></CELL>
</ROW>
</TBODY>
</TABLE>
XSLT Tried:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="no" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="table">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="TBODY/ROW/CELL[position()!=last()]/Para/refint">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="//TABLE//Para[not(normalize-space())][../#rowmerged='T']">
<xsl:variable name="cellnum" select="count(../preceding-sibling::CELL) + 1"/>
<xsl:variable name="matchingCells" select=" ../../preceding-sibling::ROW/CELL[$cellnum]/Para"/>
<xsl:copy-of select="$matchingCells[normalize-space()][last()]"/>
</xsl:template>
</xsl:transform>
Expected Output:
<?xml version="1.0" encoding="UTF-8"?>
<TABLE align="CENTER" >
<THEAD editable="T">
<ROW editable="F">
<CELL rowmerged="F" ><Para appdisplaytext=" ">S.No </Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Name</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Role</Para></CELL>
<CELL colmerged="F" ><Para appdisplaytext=" " >Comment</Para></CELL>
</ROW>
</THEAD>
<TBODY editable="T">
<ROW editable="F">
<CELL rowmerged="T" ><Para appdisplaytext=" ">S.No1 </Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Name1</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Role1</Para></CELL>
<CELL colmerged="F" ><Para appdisplaytext=" " >Comment1</Para></CELL>
</ROW>
<ROW editable="F">
<CELL rowmerged="T" ><Para appdisplaytext=" ">S.No1 </Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Name2</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Role2</Para></CELL>
<CELL colmerged="F" ><Para appdisplaytext=" " >Comment2</Para></CELL>
</ROW>
<ROW editable="F">
<CELL rowmerged="F" ><Para appdisplaytext=" ">S.No 3</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Name3</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Role3</Para></CELL>
<CELL colmerged="F" ><Para appdisplaytext=" " >Comment3</Para></CELL>
</ROW>
<ROW editable="F">
<CELL rowmerged="F" ><Para appdisplaytext=" ">S.No 4</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Name4</Para></CELL>
<CELL rowmerged="F" ><Para appdisplaytext=" ">Role4</Para></CELL>
<CELL colmerged="F" ><Para appdisplaytext=" " >Comment4</Para></CELL>
</ROW>
</TBODY>
</TABLE>
we got:
<?xml version="1.0" encoding="UTF-8"?>
<TABLE align="CENTER">
<THEAD editable="T">
<ROW editable="F">
<CELL rowmerged="F"><Para appdisplaytext=" ">S.No </Para></CELL>
<CELL rowmerged="F"> <Para appdisplaytext=" ">Name</Para></CELL>
<CELL rowmerged="F"> <Para appdisplaytext=" ">Role</Para></CELL>
<CELL colmerged="F"><Para appdisplaytext=" ">Comment</Para></CELL>
</ROW>
</THEAD>
<TBODY editable="T">
<ROW editable="F">
<CELL rowmerged="T"><Para appdisplaytext=" ">S.No1 </Para></CELL>
<CELL rowmerged="F"><Para appdisplaytext=" ">Name1</Para></CELL>
<CELL rowmerged="F"><Para appdisplaytext=" ">Role1</Para></CELL>
<CELL colmerged="F"><Para appdisplaytext=" ">Comment1</Para></CELL>
</ROW>
<ROW editable="F">
<CELL rowmerged="T"><Para appdisplaytext=" "><refint>S.No1 </refint> </Para> </CELL> (We are getting ref int here.)
<CELL rowmerged="F"> <Para appdisplaytext=" ">Name2</Para> </CELL>
<CELL rowmerged="F"> <Para appdisplaytext=" ">Role2</Para> </CELL>
<CELL colmerged="F"> <Para appdisplaytext=" ">Comment2</Para> </CELL>
</ROW>
<ROW editable="F">
<CELL rowmerged="F"> <Para appdisplaytext=" ">S.No 3</Para> </CELL>
<CELL rowmerged="F"> <Para appdisplaytext=" ">Name3</Para> </CELL>
<CELL rowmerged="F"> <Para appdisplaytext=" ">Role3</Para> </CELL>
<CELL colmerged="F"> <Para appdisplaytext=" ">Comment3</Para> </CELL>
</ROW>
<ROW editable="F">
<CELL rowmerged="F"> <Para appdisplaytext=" ">S.No 4</Para> </CELL>
<CELL rowmerged="F"> <Para appdisplaytext=" ">Name4</Para> </CELL>
<CELL rowmerged="F"> <Para appdisplaytext=" ">Role4</Para> </CELL>
<CELL colmerged="F"> <Para appdisplaytext=" ">Comment4</Para> </CELL>
</ROW>
</TBODY>
</TABLE>
The issue occurs in this template
<xsl:template match="//TABLE//Para[not(normalize-space())][../#rowmerged='T']">
<xsl:variable name="cellnum" select="count(../preceding-sibling::CELL) + 1"/>
<xsl:variable name="matchingCells" select="../../preceding-sibling::ROW/CELL[$cellnum]/Para"/>
<xsl:copy-of select="$matchingCells[normalize-space()][last()]"/>
</xsl:template>
When you match an "empty" Para element, where rowmerged is "T", then you copy the corresponding Para from the preceding ROW. But because you are using xsl:copy-of this will copy it without any further transformation. xsl:copy-of copies from the input tree, and does not take into account any transformation you may previously done on that node (which is in the output, not the input).
Try using xsl:apply-templates instead:
<xsl:template match="//TABLE//Para[not(normalize-space())][../#rowmerged='T']">
<xsl:variable name="cellnum" select="count(../preceding-sibling::CELL) + 1"/>
<xsl:variable name="matchingCells" select="../../preceding-sibling::ROW/CELL[$cellnum]/Para"/>
<xsl:apply-templates select="$matchingCells[normalize-space()][last()]"/>
</xsl:template>
By using xsl:apply-templates it will apply any transforms on the nodes you are selecting at this point.
EDIT: If you only want to copy the children of the Para node, try this template which copies the Para node being matched, but copies the children from the previous sibling.
<xsl:template match="//TABLE//Para[not(normalize-space())][../#rowmerged='T']">
<xsl:variable name="cellnum" select="count(../preceding-sibling::CELL) + 1"/>
<xsl:variable name="matchingCells" select="../../preceding-sibling::ROW/CELL[$cellnum]/Para"/>
<xsl:copy>
<xsl:apply-templates select="#*" />
<xsl:apply-templates select="$matchingCells[normalize-space()][last()]/node()"/>
</xsl:copy>
</xsl:template>
I am using the following stylesheet for displaying a table in the excel workbook with the data. I am not able to get the desired result instead it is displaying as differently as given below.
Suggestions Pls?
The stylesheet used:
<xsl:stylesheet>
<xsl:template match="/">
<xsl:variable name="test1" select="str:tokenize('1$,$2$,$3$,$4$,$5','$,$')" />
<xsl:variable name="test2" select="str:tokenize('a$,$b$,$c$,$d$,$e','$,$')" />
<xsl:for-each select="str:split('1a$,$2b$,$3c$,$4d$,$5e','$,$')>
<row>
<cell Index="1">
<xsl:value-of select="$test1[position()]" />
</cell>
<cell Index="2">
<xsl:value-of select="$test2[position()]" />
</cell>
</row>
</xsl:for-each>
</xsl:template>
Expected Result:
1 a
2 b
3 c
4 d
5 e
Where as the result displayed as
a b
c d
e
It seems like the it is displaying the latest tokenize values.
How to get respected values.
Good question, +1.
It seems to me that instead of:
<xsl:value-of select="$test1[position()]" />
this must be:
<xsl:value-of select="$test1[position() = current()]" />
Exactly the same observation holds for the second <xsl:value-of>
Explanation:
Any expression
$var[position()]
is equivalent to:
$var
because position() can only have values >= 1 and [position()] means the boolean value of position() , and the boolean value of any non-negative number by definition is true().
If we want to select the $k-th node in the node-set $var, in XPath 1.0, which is weakly-typed and it isn't known that $k holds an integer, we have to write:
$var[position() = $k]
Here is a complete, corresponding XSLT 2.0 solution:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="test1" select=
"tokenize('1$,$2$,$3$,$4$,$5','\$,\$')" />
<xsl:variable name="test2" select=
"tokenize('a$,$b$,$c$,$d$,$e','\$,\$')" />
<xsl:for-each select="tokenize('1a$,$2b$,$3c$,$4d$,$5e','\$,\$')">
<row>
<cell Index="1">
<xsl:value-of select="$test1[position()]" />
</cell>
<cell Index="2">
<xsl:value-of select="$test2[position()]" />
</cell>
</row>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
when applied on any XML document (ignored), the wanted, correct result is produced:
<row xmlns:xs="http://www.w3.org/2001/XMLSchema">
<cell Index="1">1 2 3 4 5</cell>
<cell Index="2">a b c d e</cell>
</row>
<row xmlns:xs="http://www.w3.org/2001/XMLSchema">
<cell Index="1">1 2 3 4 5</cell>
<cell Index="2">a b c d e</cell>
</row>
<row xmlns:xs="http://www.w3.org/2001/XMLSchema">
<cell Index="1">1 2 3 4 5</cell>
<cell Index="2">a b c d e</cell>
</row>
<row xmlns:xs="http://www.w3.org/2001/XMLSchema">
<cell Index="1">1 2 3 4 5</cell>
<cell Index="2">a b c d e</cell>
</row>
<row xmlns:xs="http://www.w3.org/2001/XMLSchema">
<cell Index="1">1 2 3 4 5</cell>
<cell Index="2">a b c d e</cell>
</row>