这不是唯一的问题,但我无法从其他解决方案中找出为什么我的代码是错误的。这是一个任务,我已经弄明白了,但我无法理解为什么条件永远不会评估为真。如果我构成一个虚拟句子,例如contains('a', 'a')
或甚至1=1
,那么我可以看到正确的输出(不过,未经过条件的过滤)。
另外,如果我只是尝试使用<xsl:value-of select="name(.)" />
输出当前元素的名称,则不输出任何内容。显然有些东西我没有到这里,但它正在逃避我。任何线索?
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes" encoding="ISO-8859-1"/>
<xsl:template match="/">
<xsl:apply-templates select="node()" />
</xsl:template>
<xsl:template match=".">
<xsl:if test="contains(name(.),'a')">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="child::node()" />
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
在这种情况下,XML架构根本不重要。我知道有些元素包含字母a(包括根元素)。
为什么当我调用<xsl:value-of select="name(node())" />
时,我得到XSLT文件节点的名称(“xsl:stylesheet”),而不是我的XSLT正在处理的文件中当前节点的名称文件?
谢谢!
答案 0 :(得分:2)
我很惊讶你在运行XSLT时没有收到错误,因为当我尝试使用Mircosoft的XSLT处理时,我收到错误&#34; Only&#39; child&#39 ;和&#39;属性&#39;在谓词之外的模式中允许使用轴。&#34; 。这是因为在XPath中,dot是上下文节点的缩写。
我想知道您使用的XSLT处理是否与顶级文档节点匹配match="."
(类似于匹配=&#34; /&#34;)这可以解释为什么您不是得到任何输出。
在任何情况下,您确实需要<xsl:template match="*">
,而不是<xsl:template match="." />
但是你要解决这个问题的真正目的是建立在XSLT Identity Transform上,这是XSLT中的一个基本设计模式。它本身会复制输入XML中的所有现有节点,但您可以根据需要添加额外的模板匹配。
在您的情况下,您说您只想复制包含&#39; a&#39;在名字里。好吧,反过来考虑一下,并说,在这种情况下,你不要&#34;不要&#34;想要复制那些没有“a&#39;以他们的名义。因此,您需要添加到身份转换的所有内容都是此模板
<xsl:template match="*[not(contains(name(), 'a'))]" />
顺便说一下,你真的不需要你的初始模板&#34; /&#34;这里
<xsl:template match="/">
<xsl:apply-templates select="node()" />
</xsl:template>
XSLT具有内置模板的概念,在XSLT中没有显式模板时使用。这些内置模板将输出文本节点的文本,而对于其他节点,它将继续处理子节点(不复制节点)。所以,&#34; /&#34;的所有模板;正在做的就是内置模板无论如何都要做的事情。
答案 1 :(得分:0)
您似乎缺少一些基本概念。
您有match='.'
,如果您想匹配所需的所有元素match='*'
。
因为你要求当前节点的第一个子节点的名称,并且你得到xsl:stylesheet
,这告诉我你正在用样式表作为输入XML和当前节点执行该指令节点作为根节点。
我预见到的问题是,如果文档元素不包含'a',那么您无需处理文档的其余部分。
如果你描述了你的任务是什么,而不是告诉我们什么是行不通的,那也许会有所帮助......但是,如果有人给你答案,那么你根本不会得到任何帮助,真的