XSLT混合内容节点

12

我有一个相当愚蠢的问题。如何确保我的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仅为示例,我需要处理一些更大的结构,但出于清晰起见,我没有将其包含在内。

你能分享一下你的XSLT吗? - ax.
2个回答

13

<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生成的(注意:为了可读性,我通过tidy管道处理过它。在此过程中删除了无关紧要的空白):

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

1
我永远都不会停止流口水。我想我只需要更加努力地工作,让那些讨厌的菜单自己构建起来,非常感谢! :P - Olivier Tremblay

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

可以是一个选项,尽管我必须将我的链接更改为“a”标签,其中的信息根据某些内容需要更改。 - Olivier Tremblay
啊,是的。我没看到那个,抱歉。 - cadrian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接