html - Select all child elements with all attributes of child elements in a table. -
suppose have following xml:
<parent> <child1 attr1="value" attr2="value" attr3="value"/> <child1 attr1="value" attr2="value" attr3="value"/> <child1 attr1="value" attr2="value" attr3="value"/> </parent>
i want put elements of type child1 rows table consisting of column each attribute - simple enough. problem, however, type of child element , number/types of child elements attributes vary between instances of parent. here's example of instances of parent might contain
<parent> <child2 attr1="value" attr2="value" attr3="value" attr4="value"/> <child2 attr1="value" attr2="value" attr3="value" attr4="value"/> <child2 attr1="value" attr2="value" attr3="value" attr4="value"/> </parent>
the news there never 2 types of child elements within parent, long have when clause each possible type of child element , associated attributes, can make work. bad news there lot of variations on child element , going take long time ensure i've accounted every single 1 of them.
my question - there way indiscriminately each selects child elements without looking specific type while selecting of child elements attributes table format automatically without specificying following each attribute explicitly within foreach:
<td><xsl:value-of select="attr1"/></td>
this result in varying types of tables depending on type of child element within parent instance , associated variation of attributes.
is possible or out of luck?
sure, it's possible. let's want each <parent>
node turn <table>
. (obviously, adjust select
xpath parent
nodes in incoming document).
<xsl:template match="/"> <xsl:apply-templates select="indoc/parent"/> </xsl:template> <xsl:template match="parent"> <table> <xsl:apply-templates/> </table> </xsl:template>
now, let's care element names, , want turn childnnn
nodes rows. we'll for-each
turn each attribute (the @*
xpath) <td>
.
<xsl:template match="*[starts-with(local-name(), 'child')]"> <tr> <xsl:for-each select="@*"> <td> <xsl:value-of select="concat(local-name(), ':', .)"/> </td> </xsl:for-each> </tr> </xsl:template>
if want every node under <parent>
turn row, no matter element name is, can either condense two-level nested for-each
, or use template modes:
<xsl:template match="parent"> <table> <xsl:apply-templates mode="make-row" /> </table> </xsl:template> <xsl:template match="*" mode="make-row"> <tr> <xsl:for-each select="@*"> <td> <xsl:value-of select="concat(local-name(), ':', .)"/> </td> </xsl:for-each> </tr> </xsl:template>