XSL如何使用apply-templates从一个xml节点集中选择数据

时间:2016-09-06 23:37:43

标签: xml xslt

好的,我有一个XML文档,其中包含两个不同报告的结果:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="friends.xsl"?>
<root>
<report name="Type1">
<Datarow>
<Name>Fred</Name>
<Age>39</Age>
</Datarow>
<Datarow>
<Name>George</Name>
<Age>41</Age>
</Datarow>
</report>
<report name="Type2">
<Datarow>
<Name>Sheila</Name>
<Age>20</Age>
</Datarow>
<Datarow>
<Name>Susie</Name>
<Age>23</Age>
</Datarow>
</report>
</root>

我正在使用XSL 1.0(在此示例中)转换为一个简单的XSL文件。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="report[@name='Type1']">
<table>
<tr><td>Name</td><td>Age</td></tr>
<xsl:apply-templates select="Datarow"/>
</table>
</xsl:template>

<xsl:template match="Datarow">
<tr><td> <xsl:value-of select="Name"/></td>
<td><xsl:value-of select="Age"/></td></tr>
</xsl:template>
</xsl:stylesheet>

我的理解是第一个模板匹配语句将节点指针设置在XML报告节点,其中报告名称属性为“Type1”。 然后,我有一个应用模板选择寻找Datarow。这与我的Datarow模板相匹配,该模板会返回姓名和年龄细节。

问题是它返回Type1报告的名称和年龄,在我指定的表格中格式化,但随后我将Type2报告节点中的文本作为无格式文本:

<div id="result_output">
<table style="border: solid 1px;">
<tbody><tr>
<td>Name</td>
<td>Age</td>
</tr>
<tr>
<td>Fred</td>
<td>39</td>
</tr>
<tr>
<td>George</td>
<td>41</td>
</tr>
</tbody></table>


Sheila
20


Susie
23


</div>

我做错了什么?

1 个答案:

答案 0 :(得分:0)

您需要在<report name="Type2">节点上添加模板匹配,该节点也存在于文档的根目录中。因为您没有重新设计<root>所有文档内容将显示包括具有显式模板匹配的内容。使用libxslt引擎, Sheila Susie 数据显示<tr><td>标记(由于<Datarow>模板匹配,他们会跟着)。但是输出是一个格式不正确的XML,因为新的根<table>不包含这样的节点。

要删除此不需要的节点,请考虑在不需要的报告类型上添加空模板匹配。然而,我认为这是一种后瞻性的,被动的方法。

<xsl:template match="report[@name='Type2']"/>

首选选项是重写root以仅应用所需的报告类型。这将是前瞻性的,积极主动的方法(因为其他报告类型可能存在)。此外,通常,在XSLT中,您将从<root>开始,然后在树上工作。

...
<xsl:template match="/root">
    <xsl:apply-templates select="report[@name='Type1']"/>
</xsl:template>

<xsl:template match="report">    
    <table>
        <tr><td>Name</td><td>Age</td></tr>
        <xsl:apply-templates select="Datarow"/>
    </table>
</xsl:template>
...