2

这不是唯一的问题,但我无法从其他解决方案中找出我的代码错误的原因。这是一个作业,我已经弄清楚了大部分,但我不明白为什么这个条件永远不会评估为真。如果我组成一个虚拟子句,例如,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 文档正在处理的文件中当前节点的名称?

谢谢 !

4

2 回答 2

3

我很惊讶您在运行 XSLT 时没有收到错误,因为当我使用 Mircosoft 的 XSLT 处理尝试它时,我收到错误“在谓词之外的模式中只允许 'child' 和 'attribute' 轴”。. 这是因为在 XPath 中,点是上下文节点的缩写。

我想知道您正在使用的 XSLT 处理是否匹配顶级文档节点match="."(类似于执行 match="/"),这可以解释为什么您没有得到任何输出。

无论如何,你确实需要<xsl:template match="*">这里,而不是<xsl:template match="." />

但是您真正应该做的是建立在 XSLT Identity Transform的基础上,这是 XSLT 中的一种基本设计模式。它本身会复制输入 XML 中的所有现有节点,但您可以根据需要添加额外的模板匹配。

在您的情况下,您说您只想复制名称中包含“a”的元素。好吧,反过来想,在这种情况下,你“不想”复制名称中没有“a”的元素。因此,您需要添加到身份转换中的就是这个模板

<xsl:template match="*[not(contains(name(), 'a'))]" />

顺便说一句,您在这里并不需要“/”的初始模板

<xsl:template match="/">
    <xsl:apply-templates select="node()" />
</xsl:template>

XSLT 有内置模板的概念,在 XSLT 中没有显式模板时使用。这些内置模板将为文本节点输出文本,而对于其他节点,它将继续处理子节点(不复制节点)。因此,“/”的所有模板所做的就是内置模板无论如何都会做的事情。

于 2013-08-12T13:08:50.777 回答
0

您似乎缺少一些基本概念。

你有match='.'并且如果你想匹配你需要的所有元素match='*'

并且由于您正在询问当前节点的第一个子节点的名称,并且您得到xsl:stylesheet,这告诉我您正在使用样式表作为输入 XML 并且当前节点作为根节点来执行该指令。

而且我预见到的问题是,如果文档元素不包含“a”,那么您将什么也不做来处理文档的其余部分。

如果您描述您的任务是什么,而不是向我们展示什么不起作用,也许会有所帮助......但是,如果有人给您答案,那么您根本不会得到帮助,真的。

于 2013-08-11T22:19:31.487 回答