XSLT选择模板
本文关键字:选择 XSLT | 更新日期: 2023-09-27 18:18:24
我有一个用c#编写的应用程序,需要将模板名称应用于XSLT中定义的xml文件。
XML示例:
<Data>
<Person>
<Name>bob</Name>
<Age>43</Age>
</Person>
<Thing>
<Color>Red</Color>
</Thing>
</Data>
XSLT例子:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="TargetName" />
<xsl:param name="RootPath" />
<xsl:Template Name="AgeGrabber">
<xsl:value-of select="/Person/Age" />
</xsl:Template>
<xsl:Template Name="ColorGrabber">
<xsl:value-of select="/Color" />
</xsl:Template>
</xsl:stylesheet>
假设我想运行路径为"/Data/Thing"的模板"ColorGrabber",然后运行路径为"/Data"的模板"AgeGrabber"的另一个转换。这可能吗?我想我可以传入路径和模板名称(加上顶部的2个参数),然后做一些类型的切换,但它看起来像xsl:call-template不能将参数作为名称属性。
我如何实现这个行为?
这个问题有很多问题:
-
<xsl:stylesheet version="2.0" ...
是指定的,但是,目前>NET不支持XSLT 2.0。 -
代码示例不是太有意义,因为一个XML文档不能同时包含
/Person/Age
和/Color
元素——一个格式良好的XML文档只有一个顶部元素,它可以是Person
或Color
,但不能同时包含。
如果有一个更有意义的例子:
<Person>
<Age>27</Age>
<HairColor>blond</HairColor>
</Person>
一个简单的解决方案是:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pProperty" select="'Age'"/>
<xsl:template match="/">
<xsl:value-of select="/*/*[name()=$pProperty]"/>
</xsl:template>
</xsl:stylesheet>
,当这个转换应用于上面的XML文档时,它会产生想要的结果:
27
如果感兴趣的元素的嵌套性可以是任意的,并且/或者我们需要对不同的元素做不同的处理,那么一个合适的解决方案是使用匹配模板(非命名模板):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pProperty" select="'HairColor'"/>
<xsl:template match="Age">
<xsl:if test="$pProperty = 'Age'">
This person is <xsl:value-of select="."/> old.
</xsl:if>
</xsl:template>
<xsl:template match="HairColor">
<xsl:if test="$pProperty = 'HairColor'">
This person has <xsl:value-of select="."/> hair.
</xsl:if>
</xsl:template>
</xsl:stylesheet>
当将此转换应用于相同的XML文档(如上所述)时,将再次生成正确的结果:
This person has blond hair.
最后,如果您真的想在XSLT 1.0或XSLT 2.0中模拟高阶函数(HOF),请参阅以下答案:https://stackoverflow.com/a/8363249/36305,或者了解FXSL。
更简单:准备两个应用模板规则(用于Age和Color元素),并有条件地发送适当的节点来转换-//Person/Age或//Thing/Color
你搞反了。您应该创建模板,匹配您想要使用的节点。
<xsl:stylesheet>
<xsl:template match="Person|Thing">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="Person">
<xsl:value-of select="Age" />
</xsl:template>
<xsl:template match="Thing">
<xsl:value-of select="Color" />
</xsl:template>
</xsl:stylesheet>