我正在努力使这个(xml 1.0)代码工作。我是新手,已经筋疲力尽了 尝试不同的方式。有人知道我的错误吗?
<xsl:for-each select="News/Sport">
<xsl:if test="local-name()='Basketball'">
<p>
<xsl:text>Basketball Sport</xsl:text>
</p>
<xsl:value-of select="News/Sport/Basketball/Phrases/Phrase"/>
</xsl:if>
</xsl:for-each>
当我将其转换为HTML文件时,内容不会显示。当我删除xsl:for each
和xsl:if statements
时,内容已成功展示。我只希望首先检查内容(如果它在XML文件中可用),如果是,那么它是从XML内容中获取的。
提前感谢您的帮助!
编辑:
这是我的XML代码
<News>
<Sport>
<Basketball>
<Phrases>
<Phrase>Zach Randolph recovered the opening tipoff in Game 1 of the Western Conference Finals, and he didn’t touch the ball again until the possession following the Grizzlies’ first timeout.
</Phrase>
<Phrases>
</Basketball>
</Sport>
</News>
EDIT2:
你能告诉我为什么我不能在下面的函数中应用模板吗?现在只有文字有效:(
<xsl:for-each select="News/Sport[Basketball]">
<xsl:apply-templates select="News/Sport/*" />
</xsl:for-each>
<xsl:template match="Basketball">
<p>
<xsl:text>Basketball Sport</xsl:text>
</p>
<xsl:apply-templates select="Phrases/Phrase"/>
</xsl:template>
答案 0 :(得分:1)
<xsl:for-each select="News/Sport">
<xsl:if test="local-name()='Basketball'">
在此if
测试中,上下文节点是Sport
元素,因此local-name()
始终为Sport
,永远不会与篮球相等。
我只希望首先检查内容(如果它在XML文件中可用),如果是,那么它是从XML内容中获取的。
在XSLT中处理此类事情的常用方法是定义与可能存在的各个节点匹配的 templates ,然后将模板应用于实际找到的所有节点。如果没有特定类型的节点,则相应的模板将不会触发
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" />
<xsl:template match="/">
<html>
<body>
<!-- apply templates that match all elements inside Sport, which may
be Basketball, Football, etc. -->
<xsl:apply-templates select="News/Sport/*" />
</body>
</html>
</xsl:template>
<!-- when we find a Basketball element ... -->
<xsl:template match="Basketball">
<p>
<xsl:text>Basketball Sport</xsl:text>
</p>
<xsl:apply-templates select="Phrases/Phrase"/>
</xsl:template>
<!-- when we find a Football element ... -->
<xsl:template match="Football">
<p>
<xsl:text>Football Sport</xsl:text>
</p>
<!-- whatever you need to do for Football elements -->
</xsl:template>
<xsl:template match="Phrase">
<p><xsl:value-of select="." /></p>
</xsl:template>
</xsl:stylesheet>
这样您就不需要任何明确的for-each
或if
,模板匹配逻辑会为您处理所有这些。
答案 1 :(得分:0)
您错过了上下文节点的想法。在xsl:for-each
内,您引用的所有内容都与所选节点有关或相对。因此,例如,在<xsl:for-each select="News/Sport">
内,上下文节点是Sport
元素,像<xsl:if test="local-name()='Basketball'">
这样的测试总是 false ,因为本地名称总是Sport
。
看起来您只需要<xsl:if test="Basketball">
来测试当前Basketball
节点是否有Sport
个子节点。
同样的事情适用于<xsl:value-of select="News/Sport/Basketball/Phrases/Phrase"/>
。因为所有内容都与Sport
节点相关,所以XSLT在News/Sport/Basketball/Phrases/Phrase
元素中寻找Sport
,它永远不会存在。
此外,您可以直接输入文字:此处不需要xsl:text
元素,因此您的代码应如下所示
<xsl:for-each select="News/Sport">
<xsl:if test="Basketball">
<p>Basketball Sport</p>
<xsl:value-of select="Basketball/Phrases/Phrase"/>
</xsl:if>
</xsl:for-each>
您可以通过向for-each
选项添加谓词来进一步优化此功能,以便它仅匹配Sport
个Basketball
个元素。喜欢这个
<xsl:for-each select="News/Sport[Basketball]">
<p>Basketball Sport</p>
<xsl:value-of select="Basketball/Phrases/Phrase"/>
</xsl:for-each>