XSL如何使用apply

编程入门 行业动态 更新时间:2024-10-28 06:31:31
XSL如何使用apply-templates从一个xml节点集中选择数据(XSL How to select data from one xml node set with apply-templates)

好的,我有一个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&t;/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> 
  
 

我究竟做错了什么?

OK, I have an XML document which comprises the results of two different reports:

<?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>

I am transforming this with (in this example) a simple XSL file using XSL 1.0.

<?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>

My understanding is that the first template match statement sets the node pointer at the XML report node where the report name attribute is "Type1". I then have a apply templates select looking for Datarow. This matches my Datarow template which brings back the name and age details.

The problem is that it brings back the Name and Age for the Type1 report, formatted in a table as i specified, but then I get the text from the Type2 report node as unformatted text:

<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> 
  
 

What am I doing wrong?

最满意答案

您需要在<report name="Type2">节点上添加模板匹配,该节点也存在于文档的根目录中。 因为您没有重新设计<root>所有文档内容将显示包括具有显式模板匹配的内容。 使用libxslt引擎, SheilaSusie数据显示<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> ...

You need to add a template match on the <report name="Type2"> node which also exists in the document's root. Because you do not redesign the <root> all document content will show including those with explicit template matches. With the libxslt engine, the Sheila and Susie data show with <tr> and <td> tags (due to the <Datarow> template match which they would follow). But output is a not well-formed XML since the new root, <table>, does not include such nodes.

To remove this unneeded node, consider adding an empty template match on unneeded report type. Yet, I would dub this a backward-looking, reactive approach.

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

A preferred option is to re-write the root to only apply the needed report type. This would be the forward-looking, proactive approach (since other report types may potentially exist). Also, usually, in XSLT you would begin at the <root> and then work down the tree.

... <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> ...

更多推荐

Type,xsl,电脑培训,计算机培训,IT培训"/> <meta name="description" co

本文发布于:2023-07-24 13:21:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1246282.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何使用   XSL   apply

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!