0

我有 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 &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 包含名称

4

4 回答 4

1

您需要稍微修改模板选择语句。在您的匹配语句中,您正在选择<dist_value>节点,因此在模板的其余部分中,选择语句需要相对于该<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>
于 2013-02-27T08:20:05.167 回答
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>
于 2013-02-27T08:31:48.463 回答
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 &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>
于 2013-02-27T08:36:32.530 回答
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 &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 中显示)

在此处输入图像描述

于 2013-02-27T08:55:18.963 回答