xml - Dynamic structure <td> and the value of property -
1) how add loop dynamic determination of sum of td sum of th
2) @ key = 'ip' - necessary make dynamic take value constructed t
<tr> <th>name</th> <th>type</th> <th>text</th> <xsl:for-each-group select="//folder/element/property" group-by="@key"> <th><xsl:value-of select="current-grouping-key()"/></th> </xsl:for-each-group> </tr> <tr> <td> <xsl:value-of select="@name"/> </td> <td> <xsl:value-of select="@*[name() = 'xsi:type'][1]"/> </td> <td> <xsl:value-of select="documentation"/> </td> <xsl:for-each select="..."> <td> <xsl:value-of select="string-join(property[@key='ip']/@value, ', ')"/> </td> </xsl:for-each> </tr>
input xml file
<folder name="technology & physical" type="technology"> <element xsi:type="archimate:node" name="smx_u_test"> <documentation>smx</documentation> <property key="ip" value="10.255.2.111"/> </element> <element xsi:type="archimate:node" name="cbs3cvr"> <documentation>dsr3cvr</documentation> <property key="ip" value="10.15.114.24"/> <property key="port" value="1521"/> <property key="hw"/> </element> <element xsi:type="archimate:node" name="smx"> <property key="ip" value="10.255.2.111"/> <property key="port" value="8181"/> <property key="port" value="8182"/> <property key="port" value="8184"/> </element> <element xsi:type="archimate:node" name="informatica test"> <documentation>informatica</documentation> <property key="ip" value="10.11.30.89"/> <property key="port" value="1521"/> </element> <element xsi:type="archimate:node" name="dsr3test"> <documentation>dsr3test</documentation> <property key="ip" value="10.255.3.133"/> <property key="port" value="1521"/> <property key="hw"/> </element> </folder>
outout html file
<html xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <body> <h2>technology & physical</h2> <table> <tr> <th>name</th> <th>type</th> <th>text</th> <th>ip</th> <th>port</th> <th>hw</th> </tr> <tr> <td>cbs3cvr</td> <td>archimate:node</td> <td>dsr3cvr</td> <td>10.15.114.24</td> <td>1521</td> <td/> </tr> <tr> <td>dsr3test</td> <td>archimate:node</td> <td>dsr3test</td> <td>10.255.3.133</td> <td>1521</td> <td/> </tr> <tr> <td>informatica test</td> <td>archimate:node</td> <td>informatica</td> <td>10.11.30.89</td> <td>1521</td> <td/> </tr> <tr> <td>smx</td> <td>archimate:node</td> <td/> <td>10.255.2.111</td> <td>8181, 8182, 8184</td> <td/> </tr> <tr> <td>smx_u_test</td> <td>archimate:node</td> <td>smx</td> <td>10.255.2.111</td> <td/> <td/> </tr> </table> </body> </html>
the number of element , property unlimited, , name of keys may different. used group by, if have decided, tell me. thank you!!!
you can use distinct-values
here distinct property
keys, rather xsl:for-each-group
<xsl:variable name="properties" select="distinct-values(element/property/@key)" />
(this assuming positioned on folder
element).
then, each element
in xml, can list values of properties so
<xsl:variable name="current" select="." /> <xsl:for-each select="$properties"> <td> <xsl:value-of select="$current/property[@key=current()]/@value" separator=", " /> </td> </xsl:for-each>
try xslt
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="2.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" exclude-result-prefixes="xsi"> <xsl:output method="html" doctype-public="xslt-compat" omit-xml-declaration="yes" encoding="utf-8" indent="yes" /> <xsl:template match="folder"> <xsl:variable name="properties" select="distinct-values(element/property/@key)" /> <table> <tr> <th>name</th> <th>type</th> <th>text</th> <xsl:for-each select="$properties"> <th><xsl:value-of select="."/></th> </xsl:for-each> </tr> <xsl:for-each select="element"> <tr> <td> <xsl:value-of select="@name"/> </td> <td> <xsl:value-of select="@xsi:type"/> </td> <td> <xsl:value-of select="documentation"/> </td> <xsl:variable name="current" select="." /> <xsl:for-each select="$properties"> <td> <xsl:value-of select="$current/property[@key=current()]/@value" separator=", " /> </td> </xsl:for-each> </tr> </xsl:for-each> </table> </xsl:template> </xsl:stylesheet>
i have assumed actual xml declare xsi
namespace prefix. declare in xslt make retrieving xsl:type
attribute simpler.
edit: if can use xslt 1.0 processor, won't able use distinct-values
get keys. instead need make use of technique called muenchian grouping distinct keys. (you wouldn't able use separator
attribute on xsl:value-of
).
try xslt instead:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" exclude-result-prefixes="xsi"> <xsl:output method="html" doctype-public="xslt-compat" omit-xml-declaration="yes" encoding="utf-8" indent="yes" /> <xsl:key name="properties" match="property" use="@key" /> <xsl:template match="folder"> <xsl:variable name="properties" select="//property[generate-id() = generate-id(key('properties', @key)[1])]/@key" /> <table> <tr> <th>name</th> <th>type</th> <th>text</th> <xsl:for-each select="$properties"> <th><xsl:value-of select="."/></th> </xsl:for-each> </tr> <xsl:for-each select="element"> <tr> <td> <xsl:value-of select="@name"/> </td> <td> <xsl:value-of select="@xsi:type"/> </td> <td> <xsl:value-of select="documentation"/> </td> <xsl:variable name="current" select="." /> <xsl:for-each select="$properties"> <td> <xsl:for-each select="$current/property[@key=current()]/@value"> <xsl:if test="position() > 1">,</xsl:if> <xsl:value-of select="." /> </xsl:for-each> </td> </xsl:for-each> </tr> </xsl:for-each> </table> </xsl:template> </xsl:stylesheet>
Comments
Post a Comment