我有一个XML文档来模拟这个任务层次结构:
1 Customer
1.1 Product A
1.1.1 Task Alpha
1.1.2 Task Beta
1.2 Product B
1.2.1 Task Alpha
1.2.2 Task Gamma
2 Customer
2.1 Product W
2.1.1 Task Delta
每个产品的客户,产品和任务数量不明。也可能有未知数量的子任务,所以我们可以看到:
19.16.8.17.1 Subtask Something
XML看起来像这样:
<ROWSET>
<ROW>
<PROJECT_CODE>Don't Care</PROJECT_CODE>
</ROW>
<ROW>
<PROJECT_CODE>WBS</PROJECT_CODE>
<TASK_DETAIL>
<TASKS>
<TASK>
<TASK_CODE>1</TASK_CODE>
<TASK_DESCRIPTION>Customer 1</TASK_DESCRIPTION>
<TASKS>
<TASK>
<TASK_CODE>1.1</TASK_CODE>
<TASK_DESCRIPTION>Product A</TASK_DESCRIPTION>
<TASKS>
<TASK_CODE>1.1.1</TASK_CODE>
<TASK_DESCRIPTION>Task Alpha</TASK_DESCRIPTION>
<TASKS />
<TASK_CODE>1.1.2</TASK_CODE>
<TASK_DESCRIPTION>Task Beta</TASK_DESCRIPTION>
<TASKS />
</TASKS>
</TASK>
<TASK>
<TASK_CODE>1.2</TASK_CODE>
<TASK_DESCRIPTION>Product B</TASK_DESCRIPTION>
<TASKS>
<TASK_CODE>1.2.1</TASK_CODE>
<TASK_DESCRIPTION>Task Alpha</TASK_DESCRIPTION>
<TASKS />
<TASK_CODE>1.2.2</TASK_CODE>
<TASK_DESCRIPTION>Task Gamma</TASK_DESCRIPTION>
<TASKS />
</TASKS>
</TASK>
</TASKS>
</TASK>
<TASK>
<TASK_CODE>2</TASK_CODE>
<TASK_DESCRIPTION>Customer 2</TASK_DESCRIPTION>
<TASKS>
<TASK>
<TASK_CODE>2.1</TASK_CODE>
<TASK_DESCRIPTION>Product W</TASK_DESCRIPTION>
<TASKS>
<TASK_CODE>2.1.1</TASK_CODE>
<TASK_DESCRIPTION>Task Delta</TASK_DESCRIPTION>
<TASKS />
</TASKS>
</TASK>
</TASKS>
</TASK>
</TASKS>
</TASK_DETAIL>
</ROW>
</ROWSET>
我第一次尝试使用XSLT是这样的:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="ROW">
<xsl:apply-templates select="PROJECT_CODE[.='WBS']"/>
</xsl:template>
<xsl:template match="PROJECT_CODE">
<h1><xsl:value-of select="."/></h1>
<table>
<tr>
<th>Task Code</th>
<th>Description</th>
</tr>
<xsl:for-each select="./../TASK_DETAIL/TASKS/TASK">
<tr>
<td><xsl:value-of select="TASK_CODE"/></td>
<td><xsl:value-of select="TASK_DESCRIPTION"/></td>
</tr>
<xsl:for-each select="./TASKS/TASK">
<tr>
<td><xsl:value-of select="TASK_CODE"/></td>
<td><xsl:value-of select="TASK_DESCRIPTION"/></td>
</tr>
</xsl:for-each>
</xsl:for-each>
</table>
</xsl:template>
正如您所看到的,我正在采用一种非常天真的方法来解析这个问题。我想列出所有的任务和安排;我的特定WBS的子任务,无论它有多少级别。我该怎么做?
答案 0 :(得分:3)
不是直接嵌套xsl:for-each
,而是使用xsl:template
声明一些模板并通过
xsl:call-template
如果您想要特定的命名模板或xsl:apply-templates
如果应该根据XPath表达式使用模板(在您的情况下可能就像“任务”一样简单对于基本用法xsl:apply-templates
应该足够了,但有时您希望匹配特定规则。
我会这样做(注意这是非常粗略的......我想你可以通过例如w3schools的帮助来弄清楚细节):
tasks
的一个模板和task
tasks
的模板遍历task
个节点,并为每个task
节点调用task
模板task
节点,则tasks
模板本身会再次调用tasks
模板答案 1 :(得分:2)
看起来musikk打败了我一个解释,但这是一个演示xslt,做我理解你想要的。一般情况下,请避免xsl:for-each用于您认为应该使用的大部分内容(即每个用于其他语言的内容)。相反,使用apply-templates或call-templates,如musikk所说。如果你必须多次处理相同的内容(例如,生成目录,然后是主体,然后是索引),也要读取模式(mode =“foo”)。
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="ROW[./PROJECT_CODE='WBS']">
<h1><xsl:value-of select="PROJECT_CODE"/></h1>
<table>
<tr>
<th>Task Code</th>
<th>Description</th>
</tr>
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="TASK">
<tr>
<td><xsl:value-of select="TASK_CODE"/></td>
<td><xsl:value-of select="TASK_DESCRIPTION"/></td>
</tr>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
这会产生:
<html>
<body>
<h1>WBS</h1>
<table>
<tr>
<th>Task Code</th>
<th>Description</th>
</tr>
<tr>
<td>1</td>
<td>Customer 1</td>
</tr>
<tr>
<td>1.1</td>
<td>Product A</td>
</tr>
<tr>
<td>1.2</td>
<td>Product B</td>
</tr>
<tr>
<td>2</td>
<td>Customer 2</td>
</tr>
<tr>
<td>2.1</td>
<td>Product W</td>
</tr>
</table>
</body>
</html>