如果我们有以下xml输入:
<root xmlns:ns="http://www.blabla">
<ns:element1 attribute="attr1">10</ns:element1>
<ns:element1 attribute="attr2">20</ns:element1>
<ns:element2 attribute="attr1">30</ns:element1>
<ns:element2 attribute="attr2">40</ns:element1>
</root>
如何在xslt中的for-each中定位每个元素?
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="root">
<html>
<body>
<h2>My Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Column 1</th>
<th style="text-align:left">Column 2</th>
</tr>
<xsl:for-each select="1 to 10">
<xsl:variable name="name" select="concat('element', .)"/>
<tr>
<td>
<xsl:value-of select="???what should be here???[lower-case(@attribute)='attr0']"/>
</td>
<td>
<xsl:value-of select="???same question???[lower-case(@attribute)='attr1']"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
请注意,我想遵循此过程(如果可能的话),因为输入是非常动态的,因此我们并不总是获得每一行中的所有元素。 我感谢您的帮助。
答案 0 :(得分:2)
您想要的表情是这个...
<xsl:value-of select="*[local-name() = $name][lower-case(@attribute)='attr1']"/>
...否则,由于代码是在原子值的Required item type of context item for the child axis is node(); supplied expression (.) has item type xs:integer
上下文中执行的,因此会失败,并沿xsl:for-each
的行出现错误。要解决此问题,您需要在xsl:for-each
之前的变量中保存对子元素的引用。
尝试使用此XSLT
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="root">
<html>
<body>
<h2>My Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Title</th>
</tr>
<xsl:variable name="children" select="*" />
<xsl:for-each select="1 to 10">
<xsl:variable name="name" select="concat('element', .)"/>
<tr>
<td>
<xsl:value-of select="$children[local-name() = $name][lower-case(@attribute)='attr1']"/>
</td>
<td>
<xsl:value-of select="$children[local-name() = $name][lower-case(@attribute)='attr2']"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
或稍好一点,以减少代码重复...
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="root">
<html>
<body>
<h2>My Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Title</th>
</tr>
<xsl:variable name="children" select="*" />
<xsl:for-each select="1 to 10">
<xsl:variable name="name" select="concat('element', .)"/>
<xsl:variable name="element" select="$children[local-name() = $name]"/>
<tr>
<td>
<xsl:value-of select="$element[lower-case(@attribute)='attr1']"/>
</td>
<td>
<xsl:value-of select="$element[lower-case(@attribute)='attr2']"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
注意,如果您可以控制输入XML,我真的会考虑更改它。使用元素名称对元素编号会使操作更加困难。理想情况下,您应该这样做...
<ns:element num="1" attribute="attr1">10</ns:element>
答案 1 :(得分:1)
如果您没有控制权,请尝试对元素进行计数并按如下所示按计数运行循环:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://www.blabla">
<xsl:template match="root">
<html>
<body>
<h2>My Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Column 1</th>
<th style="text-align:left">Column 2</th>
</tr>
<xsl:variable name="all-element" select="count(//*:element)"/>
<xsl:for-each select="*[concat('ns:element', (1 to $all-element))]">
<xsl:message select="."/>
<tr>
<td>
<xsl:value-of select="@attribute"/>
</td>
<td>
<xsl:value-of select="."/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>