2011-03-24 119 views
1

这里是我的模板:XSLT转换XHTML文档

<xsl:template name="rec"> 
    <xsl:for-each select="*"> 
    <div class="{local-name()}"> 
     <xsl:for-each select="@*"> 
     <xsl:attribute name="data-{local-name()}"> 
      <xsl:value-of select="."/> 
     </xsl:attribute> 
     </xsl:for-each> 
     <xsl:value-of select="text()" /> 
     <xsl:call-template name="rec" /> 
    </div> 
    </xsl:for-each> 
</xsl:template> 

给定一个文档,像这样:

<test> 
    <item value="1">Item 1 Text</item> 
    <item value="2">Item 2 Text</item> 
</test> 

以上变换将变成:

<div class="test"> 
    <div class="item" data-value="1">Item 1 Text</div> 
    <div class="item" data-value="2">Item 2 Text</div> 
</div> 

我遇到的问题是,此转换不能正确地尊重文本节点,并且我没有足够的XSLT背景来模拟e如何解决它。这里的问题:给定的XML像这样:

<para>This is a <emphasis>paragraph</emphasis> people!</para> 

我想看看下面的输出:

<div class="para">This is a <div class="emphasis">paragraph</div> people!</div> 

的问题是,我没有得到这个 - 我得到这个:

<div class="para">This is a <div class="emphasis">paragraph</div></div> 

通知失踪 '的人!'文本节点。我如何修复上面的XSLT以提供我需要的输出?

回答

4

一个问题是,

<xsl:value-of select="text()" /> 

只是选择第一子文本节点的值,并将其输出。

这样做正确的最简单的方法可能是使用<xsl:apply-templates>而不是<xsl:call-template>。的

然后代替

<xsl:for-each select="*"> 

<xsl:value-of select="text()" /> 

可以使用

<xsl:apply-templates /> 

将应用适当的模板,每个子元素和文本节点,为了不跳过任何。

下面是一个完整的实现:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 

    <xsl:template match="*"> 
     <div class="{local-name()}"> 
     <xsl:for-each select="@*"> 
      <xsl:attribute name="data-{local-name()}"> 
       <xsl:value-of select="."/> 
      </xsl:attribute> 
     </xsl:for-each> 
     <xsl:apply-templates /> 
     </div> 
    </xsl:template> 

</xsl:stylesheet> 

注意<xsl:apply-templates/>,这在没有明确select属性的操作,并且在上下文节点的所有儿童,包括文本节点,默认情况下。

默认模板用于文本节点。这个模板只是将它们复制到输出中。

样品输入:

<test> 
    <item value="1">Item 1 Text</item> 
    <item value="2">Item 2 Text</item> 
    <para>This is a <emphasis>paragraph</emphasis> people!</para> 
</test> 

产生所需的输出:

<div class="test"> 
    <div class="item" data-value="1">Item 1 Text</div> 
    <div class="item" data-value="2">Item 2 Text</div> 
    <div class="para">This is a <div class="emphasis">paragraph</div> people!</div> 
</div> 
+0

我想我看到你在这里做什么。=)这确实产生了我正在寻找的效果 - 非常感谢! – 2011-03-24 19:12:41

+0

对于正确的答案+1。 – 2011-03-25 12:54:12

+0

+1正确的答案和很好的解释。 – 2011-03-27 15:03:44