我有这个输入:
<school> <faculty> <area> <name>F1A1</name> </area> <area> <name>F1A2</name> </area> <area> <name>F1A3</name> </area> </faculty> <faculty> <area> <name>F2A1</name> </area> <area> <name>F2A2</name> </area> <area> <name>F2A3</name> </area> </faculty> <faculty> <area> <name>F3A1</name> </area> <area> <name>F3A2</name> </area> <area> <name>F3A3</name> </area> </faculty> </school>
我想得到这个输出(括号中的数字是字符串长度):
F1A1 (4) F1A2 (4) F1A3 (4) F2A1 (4) F2A2 (4) F2A3 (4) F3A1 (4) F3A2 (4) F3A3 (4)
以下是要求:
A.初始匹配必须是< xsl:template match =“/”>.
B.模板T1定义如下:
<xsl:template name="T1"> <xsl:value-of select="concat(.,' (',string-length(.),') ')"/> </xsl:template>
该脚本需要调用模板T1来生成所需的输出,并且不得以任何方式更改T1.
C.必须不依赖XSLT中的默认内置模板规则.
这是我的解决方案(看起来很奇怪):
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" indent="yes"/> <xsl:template match="/"> <xsl:for-each select="school/faculty"> <xsl:for-each select="area"> <xsl:for-each select="name"> <xsl:call-template name="T1"/> </xsl:for-each> </xsl:for-each> </xsl:for-each> </xsl:template> <xsl:template name="T1"> <xsl:value-of select="concat(.,') ')"/> </xsl:template> </xsl:stylesheet>
在一个部分,我使用< xsl:for-each select =“name”>只需将当前节点更改为name,因为我无法在调用模板时执行select.我知道,根本没有人以这种方式编写代码,因为我们将完全放弃调用模板并选择apply-template,但我只是想解决这个问题.
所以,基本上我的问题是,除了< xsl:for-each select =“name”>什么其他XSLT指令可以更改当前节点?
解决方法
答案是根据评论.您需要的指令是xsl:template(通过相应地应用模板调用).
例如,以下样式表产生与您的相同的结果:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" indent="yes"/> <xsl:template match="/"> <xsl:apply-templates select="school/faculty/area/name"/> </xsl:template> <xsl:template match="name"> <xsl:call-template name="T1"/> </xsl:template> <xsl:template name="T1"> <xsl:value-of select="concat(.,') ')"/> </xsl:template> </xsl:stylesheet>