xml - 如何使用带有自定义行名的 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”之类的后处理,但我不是不确定这是否是一种能力。
我在研究这个问题时遇到的问题是,我看到的每个示例都有非常简单的标签结构,而这些标签结构看起来很混乱和令人困惑。
解决方案
这是一种非常简单的查看方式:
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>