[XML] XSL 的问题

ZDNet软件频道 时间:2004-07-12 作者:Builderau.com.au |  我要评论(1)
本文关键词:xml
本周我们的 XML 和 Web服务专家 Kelvin Lawrence 修正了一位 Builder 澳大利亚读者编写的 XML 代码。
本文译自Builder.com,未经许可请勿转载

我编写了以下 xml 文件:

<DBC>
<Depts>
<Dept DeptName="Bread">
<Boss>Bruce</Boss><Owes>1000</Owes></Dept>
<Dept DeptName="Cake">
<Boss>Cathy</Boss><Owes>1500</Owes></Dept>
<Dept DeptName="Finance">
<Boss>Phil</Boss><Owes>60000</Owes></Dept>
</Depts>

<Employees>
<Employee Name="Bruce" DeptName="Bread"/>
<Employee Name="Bob" DeptName="Bread"/>
<Employee Name="Betty" DeptName="Bread"/>
<Employee Name="Bill" DeptName="Bread"/>
<Employee Name="Cathy" DeptName="Cake"/>
<Employee Name="Carol" DeptName="Cake"/>
<Employee Name="Chris" DeptName="Cake"/>
<Employee Name="Phil" DeptName="Finance"/>
<Employee Name="Frank" DeptName="Finance"/>
<Employee Name="Fred" DeptName="Finance"/>
</Employees>

<CantakeData>
<Cantake Name="Bruce" Make="BMW"/>
<Cantake Name="Bob" Make="Ford"/>
<Cantake Name="Betty" Make="Ford"/>
<Cantake Name="Betty" Make="Honda"/>
<Cantake Name="Cathy" Make="Ford"/>
<Cantake Name="Cathy" Make="Mazda"/>
<Cantake Name="Cathy" Make="BMW"/>
<Cantake Name="Cathy" Make="Honda"/>
<Cantake Name="Carol" Make="Ford"/>
<Cantake Name="Carol" Make="Honda"/>
<Cantake Name="Phil" Make="BMW"/>
<Cantake Name="Phil" Make="Benz"/>
<Cantake Name="Frank" Make="BMW"/>
<Cantake Name="Fred" Make="Ford"/>
<Cantake Name="Fred" Make="Mazda"/>
</CantakeData>

<Cars>
<Car><CarNr>1</CarNr><Make>Ford</Make><Cost>50</Cost>
<OutTo>Bob</OutTo><OutOn>17-Feb-2005</OutOn></Car>
<Car><CarNr>2</CarNr><Make>Ford</Make><Cost>80</Cost>
<OutTo>Cathy</OutTo><OutOn>17-Feb-2005</OutOn></Car>
<Car><CarNr>3</CarNr><Make>Mazda</Make><Cost>80</Cost></Car>
<Car><CarNr>4</CarNr><Make>BMW</Make><Cost>100</Cost></Car>
<Car><CarNr>5</CarNr><Make>BMW</Make><Cost>200</Cost></Car>
<Car><CarNr>6</CarNr><Make>BMW</Make><Cost>250</Cost>
<OutTo>Frank</OutTo><OutOn>4-Feb-2005</OutOn></Car>
<Car><CarNr>7</CarNr><Make>Benz</Make><Cost>250</Cost></Car>
<Car><CarNr>8</CarNr><Make>Benz</Make><Cost>350</Cost>
<OutTo>Phil</OutTo><OutOn>09-Dec-2004</OutOn></Car>
<Car><CarNr>9</CarNr><Make>Ford</Make><Cost>150</Cost></Car>
<Car><CarNr>10</CarNr><Make>Honda</Make><Cost>150</Cost></Car>
</Cars>

<Today>19-Feb-2005</Today>

</DBC>

现在我想使用 XSL 得到以下输出:

Department Owes Cars Out Liability Total
----------------------------------------------------------------
Bread 1000 1 150 1500
Cake 1500 1 240 1740
Finance 60000 2 29950 89550

我有一个 java 类文件用以计算债务成本(每天出车的成本)。

我现在的问题是不能得到每个部门的出车成本和债务成本输出。

下面是我目前的 XSL 文件:

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

<xsl:template match=" / ">
<html>
<title>Liability Report</title>
<center>
<table border="7"><tr>
<th colspan="5" align="left">Departmental Liability Report</th></tr> <body
style="margin-left: 50px;
margin-top: 100px;
font-family: Comic Sans MS;
background-color: #ffffbb;
color: maroon">
<tr>
<th>Dept</th>
<th>Owes</th>
<th>Cars Out</th>
<th>Liability</th>
<th>Total</th>
<xsl:for-each select="//DBC/Depts/Dept/@DeptName"><tr>
<td><xsl:value-of select="../@DeptName"/></td> <td><xsl:value-of select="../Owes"/></td>
<td><xsl:value-of select="count(//DBC/Cars/Car
[OutTo=//DBC/Employees/Employee/@Name])"/>
</td></tr>
</xsl:for-each>
</tr>
</body>
</table>
</center>
</html>
</xsl:template>
</xsl:stylesheet>

您能给我提供一些帮助或建议吗?

Kelvin:
为了弄清楚为什么会出现这种情况,我请教了我的得力的 XSL 助手 Anders Berglund。Anders 已经做了很多 XSL 方面的工作,它是 W3C XSL 工作组的一位 IBM 代表。

你的样式表需要改写新,以使得“OutTo”元素的内容匹配职员(Employee)的名称,并且使得职员(Employee)目前位于正在被 xsl:for-each 循环处理的部门中。你在问题中提交的样式表并没有考虑后者。

下面是一个修改后的样式表,这个样式表正确地提取了问题中提到的“出车成本”。Anders 实现这一点的方法是:将部门名称保存在一个叫做“dept”的变量中,并在测试中使用的 XPath 中添加一个谓词 [@DeptName = $dept]。

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

<xsl:template match=" / ">
<html>
<title>Liability Report</title>
<center>
<table border="7"><tr>
<th colspan="5" align="left">Departmental Liability Report</th></tr> <body
style="margin-left: 50px;
margin-top: 100px;
font-family: Comic Sans MS;
background-color: #ffffbb;
color: maroon">
<tr>
<th>Dept</th>
<th>Owes</th>
<th>Cars Out</th>
<th>Liability</th>
<th>Total</th>
<xsl:for-each select="//DBC/Depts/Dept/@DeptName">

<xsl:variable name="dept" select="."/>

<tr>
<td><xsl:value-of select="../@DeptName"/></td> <td><xsl:value-of
select="../Owes"/></td>
<td>

<xsl:value-of select="count(//DBC/Cars/Car
[OutTo=//DBC/Employees/Employee[@DeptName = $dept]/@Name])"/>

</td>
</tr>
</xsl:for-each>
</tr>
</body>
</table>
</center>
</html>
</xsl:template>
</xsl:stylesheet>


本文作者:Kelvin Lawrence 是 IBM 动态电子商务技术部门的 CTO。在此之前,他是 IBM xml 技术部门的 CTO。在 xml 技术部门工作时,Lawrence 集中确定 xml 技术的开发和部署。他还深入参与了各种 Internet 标准的定义,并且是 World Wide Web 协会 IBM 公司的代表。


责任编辑:李宁

欢迎评论投稿

百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134