2013-02-27 96 views
0

我有XML文件,该文件是显示数据使用XSLT

<?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 &lt; 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方含名称

回答

1

这里的另一个选项,更灵活一点,当涉及到不同的元素可以出现在/products/node/node。在/products/node/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 &lt; 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 --&gt;</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 --&gt;</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 --&gt;</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 --&gt;</td> 
      <td> 2013-08-12 17:29:00 </td> 
     </tr> 
     <tr> 
      <td></td> 
      <td>name --&gt;</td> 
      <td> test </td> 
     </tr> 
     </table> 
    </body> 
</html> 

HTML输出(IE中显示)

enter image description here

1

你需要稍微修改您的模板SELECT语句。 在你匹配的语句您选择的<dist_value>节点,所以在模板的休息,SELECT语句必须是相对于<dist_value>节点,就像这样:

<xsl:template match="products/node/node/dist_value[node &lt; 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

一件事要知道XSLT是它具有内置模板的概念。如果它正在查找模板以匹配元素,但在您的XSLT中不存在,则会使用这些模板。在你的情况,你通过查找节点元素

<xsl:apply-templates select="products/node/node" /> 

但是开始的,你的模板匹配dist_value元素

<xsl:template match="products/node/node/dist_value[node &lt; 50]"> 

这意味着XSLT将开始使用内置的模板,将输出元素的文本,然后处理任何孩子。您可能应该这样做,以匹配节点元素。

<xsl:template match="products/node/node[dist_value/node &lt; 50]"> 

虽然你还需要一个模板来匹配节点元素,其中的dist_value不低于50。或者你可以改变你的应用模板,只选择你想要

<xsl:apply-templates select="products/node/node[dist_value/node &lt; 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 &lt; 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(., '&#10;')"/> 
    </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> 
1

你的代码有很多错误。重点学习关于上下文节点,应用模板以及处理器如何迭代节点。你的模式也很尴尬;如果可以的话,考虑用“产品”替换“节点/节点”。

下面是一个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 &lt; 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"> =&gt; </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"> =&gt; </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"> =&gt; </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 =&gt; 72, 19, 49</td> 
     </tr> 
     <tr> 
      <td>reg_str_dt =&gt; 2013-10-25 17:29:00</td> 
     </tr> 
     <tr> 
      <td>product_id =&gt; 2</td> 
     </tr> 
     <tr> 
      <td align="center" rowspan="5">3</td> 
     </tr> 
     <tr> 
      <td>dist_value =&gt; 12, 548, 112</td> 
     </tr> 
     <tr> 
      <td>reg_str_dt =&gt; 2013-08-12 17:29:00</td> 
     </tr> 
     <tr> 
      <td>name =&gt; test</td> 
     </tr> 
     <tr> 
      <td>product_id =&gt; 3</td> 
     </tr> 
     </table> 
    </body> 
</html>