我有
的xml文件<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="test1.xsl"?>
<products>
<node>
<node>
<dist_value>
<node> 55 </node>
<node> 59 </node>
<node> 72 </node>
</dist_value>
<reg_str_dt>
<node> 2013-08-03 17:29:00 </node>
</reg_str_dt>
<product_id> 1 </product_id>
</node>
</node>
<node>
<node>
<dist_value>
<node> 72 </node>
<node> 19 </node>
<node> 49 </node>
</dist_value>
<reg_str_dt>
<node> 2013-10-25 17:29:00 </node>
</reg_str_dt>
<product_id> 2 </product_id>
</node>
</node>
<node>
<node>
<dist_value>
<node> 12 </node>
<node> 548 </node>
<node> 112 </node>
</dist_value>
<reg_str_dt>
<node> 2013-08-12 17:29:00 </node>
</reg_str_dt>
<name> test </name>
<product_id> 3 </product_id>
</node>
</node>
</products>
我已经写了这个xslt来显示dist_value\node < 50
的产品的所有数据,并且它将提供产品2 & 3
的输出数据
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr><th>Product ID</th><th>Product DATA</th></tr>
<xsl:apply-templates select="products/node/node" />
</table>
</body>
</html>
</xsl:template>
<xsl:template match="products/node/node/dist_value[node < 50]">
<tr>
<td><xsl:value-of select="//product_id" /></td>
<td><xsl:value-of select="products/node/node/*" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>
我是xslt的初学者,这里有些不对劲
我希望输出类似这样的东西
Product ID | Product DATA
--------------------------------
2 |dist_value => 72
| 19
| 79
|reg_str_dt => 2013-10-25 17:29:00
|product_id => 2
产品3包含名称
答案 0 :(得分:1)
您需要稍微修改模板选择语句。
在匹配语句中,您选择<dist_value>
个节点,因此在模板的其余部分中,select语句需要相对于<dist_value>
节点,如下所示:
<xsl:template match="products/node/node/dist_value[node < 50]">
<tr>
<td>
<xsl:value-of select="../product_id" />
</td>
<td>
<xsl:for-each select="./node">
<xsl:value-of select="."/>
<br/>
</xsl:for-each>
<xsl:value-of select="../reg_str_dt/node" />
</td>
</tr>
</xsl:template>
答案 1 :(得分:1)
了解XSLT的一个方面是它具有内置模板的概念。如果要查找与元素匹配的模板,但在XSLT中不存在一个模板,则将使用这些模板。在您的情况下,您可以通过查找节点元素
来开始<xsl:apply-templates select="products/node/node" />
但是,您的模板符合 dist_value 元素
<xsl:template match="products/node/node/dist_value[node < 50]">
这意味着XSLT将开始使用内置模板,它将输出元素的文本,然后处理任何子元素。您可能应该这样做以匹配节点元素。
<xsl:template match="products/node/node[dist_value/node < 50]">
虽然您还需要一个模板来匹配 dist_value 不小于50的节点元素。或者您可以更改apply-templates以仅选择那些你想要
<xsl:apply-templates select="products/node/node[dist_value/node < 50]" />
您遇到的另一个问题是 dist_value 模板
中的这一行<xsl:value-of select="//product_id" />
双斜杠意味着它将寻找相对于根元素的 product_id ,并始终选择第一个。您只需要执行此操作,以查找相对于当前节点元素的product_id
<xsl:value-of select="product_id" />
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr>
<th>Product ID</th>
<th>Product DATA</th>
</tr>
<xsl:apply-templates select="products/node/node[dist_value/node < 50]"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="products/node/node">
<tr>
<td>
<xsl:value-of select="product_id"/>
</td>
<td>
<xsl:apply-templates select="dist_value/node"/>
</td>
</tr>
<tr>
<td/>
<td>
<xsl:value-of select="reg_str_dt/node"/>
</td>
</tr>
<tr>
<td/>
<td>
<xsl:value-of select="product_id"/>
</td>
</tr>
</xsl:template>
<xsl:template match="dist_value/node">
<xsl:value-of select="concat(., ' ')"/>
</xsl:template>
</xsl:stylesheet>
应用于XML时,输出以下内容
<html>
<body>
<table border="1">
<tr>
<th>Product ID</th>
<th>Product DATA</th>
</tr>
<tr>
<td> 2 </td>
<td> 72 19 49 </td>
</tr>
<tr>
<td/>
<td> 2013-10-25 17:29:00 </td>
</tr>
<tr>
<td/>
<td> 2 </td>
</tr>
<tr>
<td> 3 </td>
<td> 12 548 112 </td>
</tr>
<tr>
<td/>
<td> 2013-08-12 17:29:00 </td>
</tr>
<tr>
<td/>
<td> 3 </td>
</tr>
</table>
</body>
</html>
答案 2 :(得分:1)
你的代码有很多错误。专注于了解上下文节点,应用模板以及处理器如何在节点上进行迭代。你的架构也很尴尬;如果可以,请考虑将“node / node”替换为“product”。
这是一个XSL:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr><th>Product ID</th><th>Product DATA</th></tr>
<xsl:apply-templates select="/products/node/node" />
</table>
</body>
</html>
</xsl:template>
<!-- ignore the node with dist_value child by default -->
<xsl:template match="node[ dist_value ]" />
<xsl:template match="node[ dist_value[node < 50] ]" priority="1.0">
<xsl:variable name="span" select="1 + count( * )" />
<tr>
<td align="center" rowspan="{$span}"><xsl:value-of select="product_id" /></td>
</tr>
<xsl:apply-templates />
</xsl:template>
<xsl:template match="name">
<tr>
<td>
<xsl:value-of select="name()" />
<xsl:text disable-output-escaping="yes"> => </xsl:text>
<xsl:value-of select="." />
</td>
</tr>
</xsl:template>
<xsl:template match="dist_value">
<tr>
<td>
<xsl:value-of select="name()"/>
<xsl:text disable-output-escaping="yes"> => </xsl:text>
<xsl:for-each select="*">
<xsl:if test="position()>1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:value-of select="normalize-space(.)" />
</xsl:for-each>
</td>
</tr>
</xsl:template>
<xsl:template match="reg_str_dt">
<tr>
<td>
<xsl:value-of select="name()"/>
<xsl:text disable-output-escaping="yes"> => </xsl:text>
<xsl:value-of select="node" />
</td>
</tr>
</xsl:template>
<xsl:template match="product_id">
<tr>
<td>
<xsl:value-of select="name()"/>
<xsl:text disable-output-escaping="yes"> => </xsl:text>
<xsl:value-of select="." />
</td>
</tr>
</xsl:template>
这是输出HTML:
<?xml version="1.0" encoding="UTF-8"?>
<html>
<body>
<table border="1">
<tr>
<th>Product ID</th>
<th>Product DATA</th>
</tr>
<tr>
<td align="center" rowspan="4">2</td>
</tr>
<tr>
<td>dist_value => 72, 19, 49</td>
</tr>
<tr>
<td>reg_str_dt => 2013-10-25 17:29:00</td>
</tr>
<tr>
<td>product_id => 2</td>
</tr>
<tr>
<td align="center" rowspan="5">3</td>
</tr>
<tr>
<td>dist_value => 12, 548, 112</td>
</tr>
<tr>
<td>reg_str_dt => 2013-08-12 17:29:00</td>
</tr>
<tr>
<td>name => test</td>
</tr>
<tr>
<td>product_id => 3</td>
</tr>
</table>
</body>
</html>
答案 3 :(得分:1)
对于/products/node/node
中可能出现的不同元素,这是另一个更灵活的选项。 node
子项内/products/node/node
个元素的数量也更灵活。
XML输入(已修改为显示一些其他测试值以显示)
<products>
<node>
<node>
<dist_value>
<node> 55 </node>
<node> 59 </node>
<node> 72 </node>
</dist_value>
<reg_str_dt>
<node> 2013-08-03 17:29:00 </node>
</reg_str_dt>
<product_id> 1 </product_id>
</node>
</node>
<node>
<node>
<dist_value>
<node> 72 </node>
<node> 19 </node>
<node> 49 </node>
</dist_value>
<reg_str_dt>
<node> 2013-10-25 17:29:00 </node>
<node>additional test value 1</node>
<node>additional test value 2</node>
</reg_str_dt>
<product_id> 2 </product_id>
</node>
</node>
<node>
<node>
<dist_value>
<node> 12 </node>
<node> 548 </node>
<node> 112 </node>
</dist_value>
<reg_str_dt>
<node> 2013-08-12 17:29:00 </node>
</reg_str_dt>
<name> test </name>
<product_id> 3 </product_id>
</node>
</node>
</products>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/products" priority="1">
<html>
<body>
<table border="1">
<tr>
<th>Product ID</th>
<th colspan="2">Product DATA</th>
</tr>
<xsl:apply-templates select="node[node/dist_value/node < 50]"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="node/node">
<tr>
<td>
<xsl:value-of select="product_id"/>
</td>
<td><xsl:value-of select="name(*[1])"/> --></td>
<td><xsl:value-of select="*[1]/*[1]"/></td>
</tr>
<xsl:apply-templates select="*[not(self::product_id)]"/>
</xsl:template>
<!--These 2 templates will handle the data on the same
row as the Product ID.-->
<xsl:template match="node/node/*[1]" priority="1">
<xsl:apply-templates mode="newrow"/>
</xsl:template>
<xsl:template match="node/node/*[1]/*[1]" mode="newrow"/>
<xsl:template match="*" mode="newrow">
<xsl:call-template name="dataRow"/>
</xsl:template>
<xsl:template match="node/node/*/*[not(position()=1)]">
<xsl:call-template name="dataRow"/>
</xsl:template>
<xsl:template name="dataRow">
<tr>
<td/>
<td/>
<td><xsl:value-of select="."/></td>
</tr>
</xsl:template>
<xsl:template match="*[not(self::node)]">
<tr>
<td/>
<td><xsl:value-of select="name()"/> --></td>
<td><xsl:apply-templates/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
HTML输出(代码)
<html>
<body>
<table border="1">
<tr>
<th>Product ID</th>
<th colspan="2">Product DATA</th>
</tr>
<tr>
<td> 2 </td>
<td>dist_value --></td>
<td> 72 </td>
</tr>
<tr>
<td></td>
<td></td>
<td> 19 </td>
</tr>
<tr>
<td></td>
<td></td>
<td> 49 </td>
</tr>
<tr>
<td></td>
<td>reg_str_dt --></td>
<td> 2013-10-25 17:29:00
<tr>
<td></td>
<td></td>
<td>additional test value 1</td>
</tr>
<tr>
<td></td>
<td></td>
<td>additional test value 2</td>
</tr>
</td>
</tr>
<tr>
<td> 3 </td>
<td>dist_value --></td>
<td> 12 </td>
</tr>
<tr>
<td></td>
<td></td>
<td> 548 </td>
</tr>
<tr>
<td></td>
<td></td>
<td> 112 </td>
</tr>
<tr>
<td></td>
<td>reg_str_dt --></td>
<td> 2013-08-12 17:29:00 </td>
</tr>
<tr>
<td></td>
<td>name --></td>
<td> test </td>
</tr>
</table>
</body>
</html>
HTML输出(在IE中显示)