首页 > 解决方案 > 如何使用带有自定义行名的 XSLT 填充表

问题描述

我仅限于使用无法自定义的 XML。它由上游进程自动生成,并创建了令人困惑的节点嵌套,尽管使用 XSLT 排序时我遇到了麻烦。我试图遍历它们以返回一个名为 FilterSize 的元素。

XML 是一个名为 Campaigns 的对象列表(其中两个)和每个对象的 FilterSize 值。目标是创建一个简单的两列表格,显示我在其过滤器大小旁边选择的名称。

问题是活动标题填写在属性“name=”下,最重要的是,它是非人类可读的,如40F0C2B3-0CA2-4E10-A3A5-8F7CF4BB9916

所以基本上我想用这些名字代替我自己的名字:Campaign1 Campaign2

然后使用 for-each 循环获取 FilterSize 的值,这些值当前位于ININ.Dialer.Campaign_FilterSize节点中。我已经能够做到后者,但我不知道如何将它们与我的自定义广告系列名称对齐。

我一直在使用 W3 学校的 TryIt 编辑器进行表格设计,这样我就可以可视化输出,这很有帮助。我试过使用1和 [0] 的 XPATH 选择器,但它只返回空白,除了1之外的任何值。似乎有效的一件事是,所以这就是我使用的。

这是 XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Statistics PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<Statistics>
   <IcServer name="localserv">
      <ININ.Dialer.Campaign>
         <ININ.Dialer_Campaign name="{40F0C2B3-0CA2-4E10-A3A5-8F7CF4BB9916}">
            <ININ.Dialer_Site name="XLSite">
               <ININ.Dialer.Campaign_FilterSize>116101</ININ.Dialer.Campaign_FilterSize>
            </ININ.Dialer_Site>
         </ININ.Dialer_Campaign>
         <ININ.Dialer_Campaign name="{657778E0-9079-4114-B639-BFD1AC3613F6}">
            <ININ.Dialer_Site name="XLSite">
               <ININ.Dialer.Campaign_FilterSize>21665</ININ.Dialer.Campaign_FilterSize>
            </ININ.Dialer_Site>
         </ININ.Dialer_Campaign>
      </ININ.Dialer.Campaign>
   </IcServer>
   <PackageName>ICBL_Admin_Clin</PackageName>
   <Description />
   <Created>20190724T184946169Z</Created>
   <Message />
   <MessageExpires>20200626T201516Z</MessageExpires>
</Statistics>

这就是我在 XSLT 中一直在玩的东西:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <h2>Campaigns</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Campaign</th>
        <th>Filter Size</th>
      </tr>
      <tr>
        <td>Campaign 1</td>
      </tr>
      <tr>
        <td>Campaign 2</td>
      </tr>
      <xsl:for-each select="//ININ.Dialer.Campaign_FilterSize">
        <td><xsl:copy-of select="node()"></td>
      </xsl:for-each>
    </table>

  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

代替循环,我还尝试使用

<xsl:value-of select="Statistics/IcServer/ININ.Dialer.Campaign"/>

但这会选择两个FilterSize 值,而不管使用选择器。

我不确定在设置表格时将循环放在哪里,因为它需要两行空间,并且需要与适当的广告系列名称相邻。

所以,理想情况下,是这样的:

相反,我无法克服这个: 不太好

我在看这篇关于创建表格的帖子这篇关于用循环做的帖子,但我似乎无法用静态内容合成循环。

我还考虑循环通过 ININ.Dialer_Campaign 节点中的“坏”名称,执行类似“如果名称等于 40F0C2B3-0CA2-4E10-A3A5-8F7CF4BB9916 则打印 Campaign 1”之类的后处理,但我不是不确定这是否是一种能力。

我在研究这个问题时遇到的问题是,我看到的每个示例都有非常简单的标签结构,而这些标签结构看起来很混乱和令人困惑。

标签: xmlxslt

解决方案


这是一种非常简单的查看方式:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/Statistics">
    <html>
        <body>
            <h2>Campaigns</h2>
            <table border="1">
                <tr bgcolor="#9acd32">
                    <th>Campaign</th>
                    <th>Filter Size</th>
                </tr>
                <xsl:for-each select="IcServer/ININ.Dialer.Campaign/ININ.Dialer_Campaign">
                    <tr>
                        <td>
                            <xsl:choose>
                                <xsl:when test="position() = 1">Your String 1</xsl:when>
                                <xsl:when test="position() = 2">Your String 2</xsl:when>
                                <!-- add more as necessary -->
                            </xsl:choose>
                        </td>
                        <td>
                            <xsl:value-of select="ININ.Dialer_Site/ININ.Dialer.Campaign_FilterSize"/>
                        </td>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
  </html>
</xsl:template>

</xsl:stylesheet>

或者,您可以设置一种查找表,因此您不依赖于输入中节点的顺序:

<xsl:for-each select="IcServer/ININ.Dialer.Campaign/ININ.Dialer_Campaign">
    <tr>
        <td>
            <xsl:choose>
                <xsl:when test="@name ='{40F0C2B3-0CA2-4E10-A3A5-8F7CF4BB9916}'">String 1</xsl:when>
                <xsl:when test="@name ='{657778E0-9079-4114-B639-BFD1AC3613F6}'">String 2</xsl:when>
                <!-- add more as necessary -->
            </xsl:choose>
        </td>
        <td>
            <xsl:value-of select="ININ.Dialer_Site/ININ.Dialer.Campaign_FilterSize"/>
        </td>
    </tr>
</xsl:for-each>

推荐阅读