XSLT 1.0:'select'表达式未计算到节点集

时间:2014-02-14 18:31:38

标签: xml xslt xslt-1.0

在应用我的XSLT 1.0样式表时,我收到以下错误:

#<RuntimeError: runtime error: element apply-templates
The 'select' expression did not evaluate to a node set.

不完全确定在何处/为何发生这种情况。这是我使用XSLT 1.0的样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" />

  <xsl:template match="/message">
  {
    "heading": "<xsl:apply-templates select="normalize-space(heading/text())"/>",
    "note_id": <xsl:apply-templates select="number(NoteID)"/>,
    "player_id": <xsl:apply-templates select="number(PlayerID)"/>,
    "team_id": <xsl:apply-templates select="number(TeamID)"/>,
    "first_name": "<xsl:apply-templates select="normalize-space(Firstname/text())"/>",
    "last_name": "<xsl:apply-templates select="normalize-space(Lastname/text())"/>",
    "position": "<xsl:apply-templates select="normalize-space(Position/text())"/>",
    "hot_cold": "<xsl:apply-templates select="normalize-space(HotCold/text())"/>",
    "status": "<xsl:apply-templates select="normalize-space(Status/text())"/>",
    "description": "<xsl:apply-templates select="Description/*"/>",
    "insight": "<xsl:apply-templates select="Insight/*"/>",
    "timestamp": "<xsl:apply-templates select="time_stamp/*"/>"
  }

  </xsl:template>

  <xsl:template match="*">
      <xsl:copy>
          <xsl:apply-templates/>
      </xsl:copy>
  </xsl:template>

  <xsl:template match="text()">
  <xsl:variable name="escaped-text">
      <xsl:call-template name="replace-string">
          <xsl:with-param name="text" select="."/>
          <xsl:with-param name="replace" select="'&quot;'" />
          <xsl:with-param name="with" select="'\&quot;'"/>
      </xsl:call-template>
  </xsl:variable>
  <xsl:value-of select="normalize-space($escaped-text)"/>
  </xsl:template>

  <xsl:template name="replace-string">
      <xsl:param name="text"/>
      <xsl:param name="replace"/>
      <xsl:param name="with"/>
      <xsl:choose>
          <xsl:when test="contains($text,$replace)">
              <xsl:value-of select="substring-before($text,$replace)"/>
              <xsl:value-of select="$with"/>
              <xsl:call-template name="replace-string">
                  <xsl:with-param name="text"
                      select="substring-after($text,$replace)"/>
                  <xsl:with-param name="replace" select="$replace"/>
                  <xsl:with-param name="with" select="$with"/>
              </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
              <xsl:value-of select="$text"/>
          </xsl:otherwise>
      </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

这里是示例XML,我只是试图转义双引号并保留<P><Description>标记中存在的任何<Insight>标记。这个特殊的例子不必处理。

<?xml version="1.0" standalone="no" ?>
<!-- <!DOCTYPE message PUBLIC "-//TSN//DTD News 1.0/EN" "PlayerNotes.dtd"> -->
<message>
<XML_File_ID>64166.194</XML_File_ID>
<heading>FHB;PNOTES-YASIEL-PUIG</heading>
<category>MLB Fantasy Sports</category>
<sport>MLB</sport>
<NoteID>104585</NoteID>
<PlayerID>22526</PlayerID>
<TeamID>005</TeamID>
<Firstname>Yasiel</Firstname>
<Lastname>Puig</Lastname>
<Position>RF</Position>
<HotCold></HotCold>
<Status></Status>
<Description>The Dodgers have limited outfielder Yasiel Puig's throwing due to right shoulder inflammation, according to mlb.com.</Description>
<Insight>Puig (.319, 19 HR, 42 RBI, 11 SB) dealt with the same issue sporadically last season and it flared up again when he overextended himself during his first day of camp. "We don't think it's serious, but we need to find out," manager Don Mattingly said.</Insight>
<time_stamp>February 14, 2014, at 08:52 AM ET</time_stamp>
</message> 

3 个答案:

答案 0 :(得分:3)

<xsl:apply-templates select="normalize-space(Status/text())"/>无法在XSLT 1.0或2.0中运行,您只能apply-templates到节点,例如<xsl:apply-templates select="Status/text()"/><xsl:apply-templates select="Status"/>,然后在包含match="text()"match="Status"的模板中,您可以调用函数normalize-space。

答案 1 :(得分:1)

看起来您传递给xsl:apply-templates的select属性的参数不是节点。 意思是“normalize-space(heading / text())”返回一个字符串而不是一个text()节点。 您应该使用“heading / text()”代替。同样适用于剩余的。

答案 2 :(得分:0)

正如其他人已经指出的那样,您必须将节点集指定为xsl:apply-templates的select属性。另请注意,<time_stamp>元素没有子元素元素 - 因此xPath表达式time_stamp/*不会选择任何内容。