[英]XSLT 1.0 - Generate HTML table using elements having unequal attribute count but same attribute name
我需要使用屬性名稱作為標題和屬性值作為數據來生成HTML表。 但是,需要循環的元素並不總是具有所有屬性。 在這種情況下,需要為所有此類不可用的屬性值將空白<td>
添加到表中。
以下是示例XML(帶有偽值的按比例縮小版本)。
<root>
<oelement attr="abc">
<ielement attr="101">
<child attr1="a" attr2="b" attr3="c" attr4="d" attr5="e" />
<child attr1="e" attr2="f" attr3="g" attr4="h" attr5="i" />
</ielement>
<ielement attr="102">
<child attr1="x" attr3="y" attr5="w" />
<child attr1="j" attr3="k" attr5="l" />
</ielement>
</oelement>
<oelement attr="pqr">
<ielement attr="101">
<child attr1="g" attr2="j" attr3="t" attr4="y" attr5="r" />
<child attr1="d" attr2="q" attr3="a" attr4="c" attr5="b" />
</ielement>
<ielement attr="102">
<child attr1="t" attr3="y" attr5="u" />
<child attr1="i" attr3="o" attr5="p" />
</ielement>
</oelement>
<oelement attr="xyz">
<ielement attr="101">
<child attr1="h" attr2="o" attr3="u" attr4="z" attr5="x" />
</ielement>
<ielement attr="103">
<child attr1="q" attr3="w" attr5="e" />
</ielement>
</oelement>
</root>
輸出HTML
我試圖將以下XSLT放在一起,但是在將數據加載到表的適當列中時,它與列標題中的屬性名稱不匹配。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:strip-space elements="*" />
<xsl:template match="root">
<html>
<body>
<table border="1" cellspacing="0" cellpadding="5">
<tr>
<th>oelement</th>
<th>ielement</th>
<xsl:for-each select="//oelement[1]/ielement[1]/child[1]/@*">
<th><xsl:value-of select="local-name()" /></th>
</xsl:for-each>
</tr>
<xsl:apply-templates />
</table>
</body>
</html>
</xsl:template>
<xsl:template match="child">
<tr>
<td><xsl:value-of select="ancestor::oelement/@attr" /></td>
<td><xsl:value-of select="ancestor::ielement/@attr" /></td>
<xsl:for-each select="@*">
<td><xsl:value-of select="." /></td>
</xsl:for-each>
</tr>
</xsl:template>
</xsl:stylesheet>
在為不匹配的列添加值和插入空白值時,需要進行列匹配方面的幫助。 我被XSLT 1.0
所困,無法升級到XSLT 2.0
以查找屬性名稱的distinct-values()
。
XLST 1.0中沒有很好的解決方案。
但是,您可以使用鍵來達到所需的效果:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:strip-space elements="*" />
<xsl:key name="child-by-attr-name" match="child/@*" use="name(.)"/>
<xsl:template match="root">
<html>
<body>
<table border="1" cellspacing="0" cellpadding="5">
<!-- skipped for simplicity -->
<xsl:apply-templates />
</table>
</body>
</html>
</xsl:template>
<xsl:template match="child">
<tr>
<td><xsl:value-of select="ancestor::oelement/@attr" /></td>
<td><xsl:value-of select="ancestor::ielement/@attr" /></td>
<xsl:variable name="current-child" select="."/>
<xsl:for-each select="(//child/@*)[generate-id(.) = generate-id(key('child-by-attr-name',name(.))[1])]">
<td>
<xsl:value-of select="$current-child/@*[name(.) = name(current())]" />
</td>
</xsl:for-each>
</tr>
</xsl:template>
這里的“技巧”是該鍵將通過其名稱索引所有屬性(在每個child
元素中)。 當您通過屬性名稱查詢關鍵字時,您會以文檔順序獲得所有具有該名稱的屬性。 然后,您可以使用generate-id()來確保僅獲得每個名稱的第一個。
成功的關鍵是通過屬性名稱循環的正確方法。
為此,我使用了:
attrib
),匹配child
屬性並保存其名稱( name()
)。 為了應對模板匹配child
上下文對象的更改,並且為了提高可讀性,我使用了2個變量:
curr
當前的child
元素。 nn
當前屬性的名稱。 因此,整個腳本如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:strip-space elements="*" />
<xsl:key name="attrib" match="child/@*" use="name()"/>
<xsl:template match="root">
<html>
<body>
<table>
<tr>
<th>oelement</th>
<th>ielement</th>
<xsl:for-each select="//child/@*[generate-id()=generate-id(key('attrib', name())[1])]">
<th><xsl:value-of select="name()"/></th>
</xsl:for-each>
</tr>
<xsl:apply-templates select="//child"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="child">
<tr>
<td><xsl:value-of select="ancestor::oelement/@attr" /></td>
<td><xsl:value-of select="ancestor::ielement/@attr" /></td>
<xsl:variable name="curr" select="."/>
<xsl:for-each select="//child/@*[generate-id()=generate-id(key('attrib', name())[1])]">
<td>
<xsl:variable name="nn" select="name()"/>
<xsl:value-of select="$curr/@*[name()=$nn]"/>
</td>
</xsl:for-each>
</tr>
</xsl:template>
</xsl:stylesheet>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.