XSLT - 动态添加元素
Posted
技术标签:
【中文标题】XSLT - 动态添加元素【英文标题】:XSLT - Adding Elements dynamically 【发布时间】:2010-11-30 12:40:58 【问题描述】:我需要以表格形式显示某些 XML 内容(用于 pdf 报告的 XSL-FO), 并且并非所有要显示的列都存在于源 XML 中。所以,我想知道 如果有一种方法可以通过嵌入额外的列来转换源 XML 某些元素值,然后处理生成的 XML 以显示内容?
例如,对于源数据:
我希望数据显示为:
姓名 角色 开发 QA -------------------------- John Doe 开发 100 保罗编码器开发 40 亨利测试仪 qa 80 彼得测试员 QA 40 -------------------------- 角色总数:140 120 --------------------------我想知道我是否可以使用类似的东西:
这样我就可以在运行时嵌入元素
使用以下样式表(页面格式 省略细节以保持简短),但我不相信这是恰当的解决方案。
...【问题讨论】:
【参考方案1】:如果添加了除开发人员和 QA 之外的更多工作角色,会发生什么情况?你的样式表能应付吗?也许您可以利用 Muenchian Grouping 来获取样式表中所有可能的角色,然后为每个可能的角色动态生成列?
<xsl:key name="roles" match="role" use="."/>
<xsl:template match="/projectteam">
<table border="1">
<tr>
<td>Name</td>
<td>Role</td>
<xsl:for-each select="member[generate-id(role) = generate-id(key('roles', role)[1])]">
<td>
<xsl:value-of select="role"/>
</td>
</xsl:for-each>
</tr>
<xsl:apply-templates select="member"/>
</table>
</xsl:template>
<xsl:template match="member">
<xsl:variable name="currentrole" select="role"/>
<xsl:variable name="currenthrs" select="hrs"/>
<tr>
<td>
<xsl:value-of select="name"/>
</td>
<td>
<xsl:value-of select="role"/>
</td>
<xsl:for-each select="/projectteam/member[generate-id(role) = generate-id(key('roles', role)[1])]">
<td>
<xsl:choose>
<xsl:when test="$currentrole = role">
<xsl:value-of select="$currenthrs"/>
</xsl:when>
</xsl:choose>
</td>
</xsl:for-each>
</tr>
</xsl:template>
我输出的是 html,而不是 XSL-FO,但也许这会给你大致的想法。
【讨论】:
谢谢!!我试过了,效果很好!这真的是一个很好的通用解决方案!现在我知道了“generate0id()”和关键元素的一些用例!我已经固定了一组类似列的“角色”(尽管有 11 个),所以这种方法会大大减少代码,但是再次动态地引入 11 个新元素会使最后对它们进行总计变得容易得多。我将尝试这种方法和多通道样式表(使用 node-set()),看看哪个更有意义。谢谢【参考方案2】:是的,你可以。
回答你的问题。确实,我还没有阅读过庞大的样式表。
【讨论】:
你能建议怎么做吗?我尝试了各种组合,但没有任何效果。我遇到的真正问题有点复杂,即我有一个可以有多个容器的邮件元素,每个容器都可以有多个捆绑包。每个捆绑包都有一个特定的 LevelType,并且有一个描述 TotalPieces 的元素。因此,要显示每个 buldle 的 TotalPieces,在其 LevelType 的列中显示它有点棘手,并且在底部显示每个 levelType 的总数变得更加混乱。这是我非常怀念添加新元素的能力的地方(即 LevelType w/value 设置为 TotalPieces)。谢谢 就像你说的那样:<xsl:element name="role" />
(在你的例子中当然是member
)。我以为你没试过。究竟什么不适合你,也不适合说什么?
好吧,我添加了一个新模板:<xsl:template match="member"> <xsl:element name="role"> <xsl:value-的 select="hrs"/> <xsl:apply-templates select="member"/> </xsl:element> </xsl:template>并尝试在成员的现有模板,但它不起作用(尽管我仍然不清楚模板)我尝试在成员的现有模板中添加这些行:
<xsl:element name="role"> < ;xsl:value-of select="hrs"/> </xsl:element>我得到的只是来自 FOP 的关于未知格式对象的警告。 第二次尝试:(prev. post 搞砸了) 1.
<dev/>
元素。我宁愿一步一步解决问题。首先,您需要为 fop 生成输入,并查看它是否是您想要的。将您的想法建立在您仅根据 fop 的消息生成的 xml 上对我来说听起来是错误的。以上是关于XSLT - 动态添加元素的主要内容,如果未能解决你的问题,请参考以下文章