【问题标题】:XSLT: in a <p> element, how to replace a line break (<br/>) with successive <alinea> element?XSLT:在 <p> 元素中,如何用连续的 <alinea> 元素替换换行符 (<br/>)?
【发布时间】:2019-02-08 01:41:18
【问题描述】:

我正在尝试将带有&lt;br/&gt; 元素的&lt;p&gt; 元素转换为多个&lt;alinea&gt;subtext&lt;/alinea&gt;。例如:

<p>subtext<br/>some more text<br/> some more subtext</p>

由于&lt;p&gt; 的模板已经打开了&lt;alinea&gt; 元素,所以我希望从之前的&lt;p&gt; 简单地将所有&lt;br/&gt; 替换为&lt;/alinea&gt;&lt;alinea&gt;

<xsl:template match="p">
    <para><alinea><xsl:apply-templates/></alinea></para>
</xsl:template>

<xsl:template match="br">
    </alinea><xsl:apply-templates/><alinea>
</xsl:template>

但它没有验证。

预期结果:

<para>
   <alinea>
     subtext
   </alinea>
   <alinea>
     some more text
   </alinea>
   <alinea>
     some more subtext
   </alinea>
 </para>

【问题讨论】:

  • 您能提供输入 XML 吗?
  • 在问题中完成。谢谢。
  • 如果输入的 XML 包含其他元素怎么办,例如:&lt;p&gt;subtext&lt;br/&gt;some more text&lt;br/&gt; some more subtext &lt;div&gt;abc&lt;/div&gt;&lt;/p&gt;?
  • 似乎有效,我只想为&lt;div&gt; 添加一个模板:xsltfiddle.liberty-development.net/jyH9rMD/1
  • 此类问题应标记为“xslt 1.0”或“xslt 2.0”。使用 2.0 构造的解决方案通常要容易得多,但并不是每个人(遗憾的是)都可以使用 XSLT 2.0(或 3.0)处理器。

标签: xslt xpath xslt-2.0 line-breaks


【解决方案1】:

这在 XSLT 2.0 中很容易做到:

<xsl:template match="p">
    <para>
        <xsl:for-each-group select="node()" group-starting-with="br">
            <alinea>
                <xsl:copy-of select="current-group()[not(self::br)]" />
            </alinea>   
        </xsl:for-each-group>
    </para>
</xsl:template>

演示https://xsltfiddle.liberty-development.net/6r5Gh2Q

【讨论】:

    【解决方案2】:

    可能你可以使用这样的东西:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:template match="p">
        <para>
          <xsl:apply-templates/>
        </para>
      </xsl:template>
    
      <xsl:template match="text()">
        <aline>
          <xsl:value-of select="."/>
        </aline>
      </xsl:template>
    
      <xsl:template match="br"/>
    
      <xsl:template match="div">
        <blockquote>
          <xsl:value-of select="."/>
        </blockquote>
      </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 我预计您的解决方案会将&lt;alinea&gt; 元素放在文本中的任何位置。例如,强调&lt;p&gt;Hello &lt;em&gt;World&lt;/em&gt;&lt;/p&gt; 的文本将导致&lt;para&gt;&lt;alinea&gt;Hello&lt;/alinea&gt;&lt;alinea&gt;World&lt;/alinea&gt;&lt;/para&gt;
    【解决方案3】:

    我找到了一种(肮脏的?)方法将&lt;br&gt; 替换为&lt;/alinea&gt;&lt;alinea&gt;

      <xsl:template match="br">
         <xsl:value-of disable-output-escaping="yes">
            &lt;/alinea&gt;&lt;alinea&gt;
         </xsl:value-of>
      </xsl:template>
    

    还有更漂亮的吗?

    【讨论】:

    • 我很乐意对否决票做出解释,因为该解决方案非常有效! :)
    • 我反对任何使用 DOE 创建标记的答案。
    猜你喜欢
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    • 2019-01-11
    相关资源
    最近更新 更多