Question:
There is an XML file with N nodes (n> = 1). XSL is used to convert the N nodes to the HTML table tag. The table has two columns, put 1st, 3, and 5 in the left column ...... Nodes. The columns on the right are 2nd, 4, and 6 ...... Nodes.
Analysis:
Table is a set of rows (<tr>) and row is a set of cells (<TD>). Based on this feature, it is attempted to locate the node directly by the parity of the node index, the column generation method is not feasible.
The table should be generated according to rows.
N may be an odd or even number. Because n> = 1, the total number of rows is equal to the odd number in N.
The program flow is a for-each loop. If the result is true, a row is created. After the row is created, two cells are created, and the first column is placed at the odd node, the second column is placed on the next node of the odd node. It mainly uses two XSLT elements: XSL: For-each and XSL: variable.
XML code:
<? XML version = "1.0" encoding = "gb2312"?>
<? XML-stylesheet type = 'text/XSL 'href = '3. XSL'?>
<Subject>
<Class>
<Classid> 1 </classid>
<Text> data 1 </text>
</Class>
<Class>
<Classid> 2 </classid>
<Text> data 2 </text>
</Class>
<Class>
<Classid> 3 </classid>
<Text> data 3 </text>
</Class>
<Class>
<Classid> 4 </classid>
<Text> data 4 </text>
</Class>
<Class>
<Classid> 5 </classid>
<Text> data 5 </text>
</Class>
</Subject>
XSL code:
<? XML version = '1. 0' encoding = 'gb2312 '?>
<XSL: stylesheetversion = "1.0"
Xmlns = "http://www.w3.org/TR/REC-html40"
Xmlns: XSL = "http://www.w3.org/1999/XSL/Transform">
<XSL: template match = "/">
<Table border = "1">
<XSL: For-each select = "// class">
<XSL: If test = "(position () mod 2 = 1)">
<XSL: variable name = "N" select = "position ()"/>
<Tr> <TD> <XSL: value-of select = "."/> </TD>
<TD> <XSL: value-of select = "// class [$ n + 1]"/> </TD> </tr>
</XSL: If>
</XSL: For-each>
</Table>
</XSL: Template>
</XSL: stylesheet>
The running result is:
1 Data 1 2 Data 2
3 Data 3 4 data 4
5. Data 5
Optimize the above XSL
The method above retrieves n nodes, which is not very efficient. You can use XPath to query an odd number of nodes, reducing the number of searches by half. So we have the following XSL:
<? XML version = '1. 0' encoding = 'gb2312 '?>
<XSL: stylesheetversion = "1.0"
Xmlns = "http://www.w3.org/TR/REC-html40"
Xmlns: XSL = "http://www.w3.org/1999/XSL/Transform">
<XSL: template match = "/">
<Table border = "1">
<XSL: Apply-templates select = "// class [position () mod 2 = 1]"/>
</Table>
</XSL: Template>
<XSL: template match = "// class [position () mod 2 = 1]">
<XSL: variable name = "N" select = "position ()"/>
<Tr> <TD> <XSL: value-of select = "."/> </TD>
<TD> <XSL: value-of select = "// class [$ n + 1]"/> </TD> </tr>
</XSL: Template>
</XSL: stylesheet>
The running result is:
1 Data 1 2 Data 2
3. Data 3. Data 3
5 Data 5 4 data 4
Why? The position function returns the index of the node. Isn't it correct? Note that the indexing depends on the parent of the node. In the two XSL mentioned above, the parent of the node is // class and // class [position () moD 2 = 1], so the second XSL does not generate the expected results.
In the second XSL, the formula for converting the possition of the node and the index of the node on the parent node is as follows: n = 2 * position ()-1, the next sibling node of the node is 2 * position (). Modify <XSL: value-of select = "// class [$ n + 1]"/> to <XSL: value-of select = "// class [$ N * 2]"/>, the output result is correct.
The running result is:
1 Data 1 2 Data 2
3 Data 3 4 data 4
5. Data 5