XML to XHTML transformation



我需要将XML转换为XHTML。XML中有多个段落和嵌入式引文,例如

<para>SomeText</para>
<para><quote>SomeText</quote></para>
<para>SomeText</para>

我试过这个:

<xsl:choose>
    <xsl:when test="//text/para">
        <xsl:for-each select="//text">
            <xsl:for-each select="//para">
                <p><xsl:value-of select="text()"/></p>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:when>
    <xsl:when test="//text/para[quote]">
        <xsl:for-each select="//text">
            <xsl:for-each select="//para/quote">
                <p><q><xsl:value-of select="text()"/></q></p>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:when>
</xsl:choose>

但是,第二个条件只是被忽略了。

如@LarsH所示,请避免<xsl:for-each>。使用模板匹配。

这个简单的转换:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="para">
    <p><xsl:apply-templates /></p>
  </xsl:template>
  <xsl:template match="quote">
    <q><xsl:apply-templates /></q>
  </xsl:template>
</xsl:transform>

将把这个转过来:

<text>
  <para>SomeText</para>
  <para><quote>SomeText</quote></para>
  <para>SomeText</para>
</text>

<p>SomeText</p>
<p><q>SomeText</q></p>
<p>SomeText</p>

进一步阅读这里 SO:

  • XSL 中的"调用模板"和"应用模板"之间有什么区别?
  • 为什么 XSLT 默认输出所有文本?
  • XSLT 应用模板的默认选择是什么?

问题是您正在使用忽略上下文(上下文文档除外)的 XPath 表达式,即以 // 开头的表达式。因此,如果文档中任何具有<quote>子元素的 <para> 元素,则第一个条件将始终为 true,而第二个条件将永远不会达到。

实际上,您希望将for-each循环(或者可能更好的是,一组具有匹配模式和应用模板的模板)移动到选择/时间条件之外。事实上,一旦你有了正确的模板,你可能根本不需要选择/什么时候。

(从评论中移入一些信息)

XSLT 和 XPath 非常复杂,在尝试通过试错法获得某些工作之前,确实值得学习基础知识。这样您将节省大量时间。对于一般介绍,我会推荐

  • XSLT 的工作原理

然后进行更高级的讨论 xsl:for-eachxsl:apply-templates ,请参阅

  • Jeni Tennison 的博客文章匹配模板、命名模板还是每个模板?我的经验法则
  • XSL 中的 for-each 和模板之间的差异?

相关内容

  • 没有找到相关文章

最新更新