代码之家  ›  专栏  ›  技术社区  ›  Olivier Tremblay

XSLT混合内容节点

  •  11
  • Olivier Tremblay  · 技术社区  · 16 年前

    我有一个非常愚蠢的问题。如何确保我的XML混合内容节点不会混淆?我有一个类似的XML结构。

    <root>
     <book>
      <title>Stuff</title>
      <description> This book is <i>great</i> if you need to know about stuff.
                    I suggest <link ref="Things">this one</link> if you need to know
                    about things. </description>
     </book>
     [other books]
    </root> 
    

    我需要最后的内容看起来像这样

    <h1>List of books</h1>
    <h2><a name="Stuff"/>Stuff</h2>
    <p> This book is <i>great</i> if you need to know about stuff.
        I suggest <a href="#Things">this one</a> if you need to know
        about things. </p>
    

    但是我不能提取文本节点的部分,我总是抓取整个内容。我用的是后代轴。你知道我做错了什么吗?

    这是我的XSLT:

    <xsl:template match="description/*">
        <xsl:for-each select="following-sibling::*">
                <xsl:choose>
                <xsl:when test="name(.)='link'">
                    <a href="{@ref}"><xsl:value-of select="."/></a>
                </xsl:when>
                <xsl:when test="name(.)='em'">
                    <em><xsl:value-of select="."/></em>
                </xsl:when>
                <xsl:otherwise><p><xsl:value-of select="."/></p></xsl:otherwise>    
            </xsl:choose>
        </xsl:for-each>
      </xsl:template>
    

    请注意,所附的XML和由此产生的HTML仅仅是示例,为了清晰起见,我必须处理一个更大的结构,而不是包含在其中。

    2 回复  |  直到 16 年前
        1
  •  11
  •   Tomalak    16 年前

    <xsl:apply-templates> 是你的朋友:

    <xsl:stylesheet 
      version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    >
      <xsl:output method="html" />
    
      <xsl:template match="root">
        <h1>List of books</h1>
        <xsl:apply-templates />
      </xsl:template>
    
      <!-- a <book> consists of its <title> and <description> -->
      <xsl:template match="book">
        <xsl:apply-templates select="title" />
        <xsl:apply-templates select="description" />
      </xsl:template>
    
      <!-- <title> is turned into a <h2> -->
      <xsl:template match="title">
        <h2>
          <a name="{.}"/>
          <xsl:value-of select="." />
        </h2>
      </xsl:template>
    
      <!-- <description> is turned into a <p> -->
      <xsl:template match="description">
        <p>
          <xsl:apply-templates />
        </p>
      </xsl:template>
    
      <!-- default rule: copy any node beneath <description> -->
      <xsl:template match="description//*">
        <xsl:copy>
          <xsl:copy-of select="@*" />
          <xsl:apply-templates />
        </xsl:copy>
      </xsl:template>
    
      <!-- override rule: <link> nodes get special treatment -->
      <xsl:template match="description//link">
        <a href="#{@ref}">
          <xsl:apply-templates />
        </a>
      </xsl:template>
    
      <!-- default rule: ignore any unspecific text node -->
      <xsl:template match="text()" />
    
      <!-- override rule: copy any text node beneath description -->
      <xsl:template match="description//text()">
        <xsl:copy-of select="." />
      </xsl:template>
    
    </xsl:stylesheet>
    

    为输入XML生成以下输出( 注意:为了可读性,我把它整齐地排好。过程中删除了不相关的空白 ):

    <h1>List of books</h1>
    <h2><a name="Stuff">Stuff</h2>
    <p>This book is <i>great</i> if you need to know about stuff. I
    suggest <a href="#Things">this one</a> if you need to know about
    things.</p>
    
        2
  •  0
  •   cadrian    16 年前
    <root>
     <book>
      <title>Stuff</title>
      <description><![CDATA[
          This book is <i>great</i> if you need to know about stuff.
          I suggest <link ref="Things">this one</link> if you need to know
          about things.
      ]]></description>
     </book>
     [other books]
    </root>