c# - XSLT 和递归生成表
问题描述
我是 XSLT 的新手,在尝试格式化具有递归节点的 XML 文档时遇到了一些问题。
树节点有两种样式,即组和数据。
问题是当节点混合了组和数据样式时,我当前的 XSLT 模板无法生成内容。
XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="Nodes[TreeNode]">
<xsl:apply-templates select="TreeNode" />
</xsl:template>
<xsl:template match="Nodes[not(TreeNode)]" />
<xsl:template match="TreeNode[Style='Data']">
<!--<table>
<thead>
<tr>
<th scope="col">Value</th>
</tr>
</thead>
<tbody>-->
<tr>
<td>
<xsl:value-of select="Value"/>
</td>
</tr>
<!--</tbody>
</table>-->
</xsl:template>
<xsl:template match="TreeNode[Style='Group']">
<group>
<p>
<xsl:value-of select="Label"/>
</p>
<xsl:apply-templates select="Nodes" />
</group>
</xsl:template>
</xsl:stylesheet>
XML
<?xml version="1.0" encoding="utf-8"?>
<TreeNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Label>Root</Label>
<Style>Group</Style>
<Nodes>
<TreeNode>
<Label>A</Label>
<Style>Group</Style>
<Nodes>
<TreeNode>
<Label>B</Label>
<Style>Group</Style>
<Nodes>
<TreeNode>
<Label />
<Value>AAA</Value>
<Style>Data</Style>
<Nodes />
</TreeNode>
<TreeNode>
<Label />
<Value>BBB</Value>
<Style>Data</Style>
<Nodes />
</TreeNode>
</Nodes>
</TreeNode>
<TreeNode>
<Label>C</Label>
<Style>Group</Style>
<Nodes>
<TreeNode>
<Label />
<Value>CCC</Value>
<Style>Data</Style>
<Nodes />
</TreeNode>
<TreeNode>
<Label />
<Value>DDD</Value>
<Style>Data</Style>
<Nodes />
</TreeNode>
</Nodes>
</TreeNode>
<TreeNode>
<Label>D</Label>
<Style>Group</Style>
<Nodes>
<TreeNode>
<Label />
<Value>EEE</Value>
<Style>Data</Style>
<Nodes />
</TreeNode>
</Nodes>
</TreeNode>
</Nodes>
</TreeNode>
</Nodes>
</TreeNode>
预期结果:
解决方案
您的 XSLT 开头有两个模板
<xsl:template match="Nodes[TreeNode]">
<xsl:apply-templates select="TreeNode" />
</xsl:template>
<xsl:template match="Nodes[not(TreeNode)]" />
这些实际上可以合并为一个;像这样:
<xsl:template match="Nodes">
<xsl:apply-templates select="TreeNode" />
</xsl:template>
原因是如果Nodes
它下面没有a TreeNode
,那么<xsl:apply-templates select="TreeNode" />
无论如何都不会选择任何东西,所以效果是一样的。(事实上,如果Nodes
只能TreeNode
在它下面有这个模板,你可以完全放弃它,因为 XSLT 的内置模板会做同样的事情)。
但是,为了回答您的问题,我认为您需要的是另一个模板,您需要另一个模板,在“数据”Nodes
有一个子项的情况下匹配TreeNode
<xsl:template match="Nodes[TreeNode/Style='Data']">
<table>
<xsl:apply-templates select="TreeNode" />
</table>
</xsl:template>
试试这个 XSLT
<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="Nodes[TreeNode/Style='Data']">
<table>
<xsl:apply-templates select="TreeNode" />
</table>
</xsl:template>
<xsl:template match="Nodes">
<xsl:apply-templates select="TreeNode" />
</xsl:template>
<xsl:template match="TreeNode[Style='Data']">
<tr>
<td>
<xsl:value-of select="Value"/>
</td>
</tr>
</xsl:template>
<xsl:template match="TreeNode[Style='Group']">
<group>
<p>
<xsl:value-of select="Label"/>
</p>
<xsl:apply-templates select="Nodes" />
</group>
</xsl:template>
</xsl:stylesheet>
推荐阅读
- arrays - 函数无法在 JSX 列中呈现注释
- c# - 在 SQL 数据库中插入动态列
- unity3d - 如何将 2d 动画导出为 png 文件?
- android - Flutter:getApplicationSupportDirectory 作为同步方法
- actions-on-google - 我们可以用超过 8000 个关于 dialogflow 和 amazon alexa 的问题来制作常见问题解答技能吗?
- javascript - 如何阻止调整大小栏如此故障?
- ios - XCode 构建系统:弄乱预处理器定义和包含的头文件?
- android - 错误:未知参数--licenses颤振医生--android-licenses
- javascript - 在javascript函数之后,图像边距没有推到浏览器页面的边缘
- javascript - 是否可以在同一个 Ejs 页面上显示集合(mongoDb)和所有集合中的每个元素?