1

我试图使这个(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>

编辑2:

你能告诉我为什么我不能在下面的函数中应用模板吗?现在只有文字有效:(

<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>
4

2 回答 2

1
<xsl:for-each select="News/Sport">

    <xsl:if test="local-name()='Basketball'">

在这个if测试中,上下文节点是一个Sport元素,所以local-name()永远Sport和永远不会等于篮球。

我只希望首先检查内容(如果它在 XML 文件中可用),如果是,那么它是从 XML 内容中获取的。

在 XSLT 中处理此类事情的常用方法是定义与可能存在的各种节点匹配的模板,然后将模板应用于实际找到的所有节点。如果没有特定类型的节点,则不会触发相应的模板

<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-eachor if,模板匹配逻辑会为你处理这一切。

于 2013-05-20T20:38:20.433 回答
0

您缺少上下文节点的想法。在 axsl:for-each中,您引用的所有内容都与所选节点有关或相对。因此,例如,在 内<xsl:for-each select="News/Sport">,上下文节点是Sport元素,并且类似的测试<xsl:if test="local-name()='Basketball'">始终为,因为本地名称始终为Sport

看起来您只想测试当前节点<xsl:if test="Basketball">是否有任何子节点。BasketballSport

同样的事情也适用于<xsl:value-of select="News/Sport/Basketball/Phrases/Phrase"/>. 因为一切都与Sport节点相关,所以 XSLTNews/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>
于 2013-05-20T20:39:45.557 回答