避免在混合内容元素中换行

Avoid newline within mixed content elements

我需要根据(不)在某些结果元素之前设置换行符来控制 XSL 转换过程的输出。接受这个输入

<text>
<line>My text uses <hi>highlighting</hi> methods</line>
<line>Next line uses <hi>two </hi><hi>highlighter</hi> elements...</line>
</text>

由这个简单的样式表转换:

<?xml version="1.0" encoding="utf-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output indent="yes" method="xml"/>

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

  <xsl:template match="hi">
    <span>
      <xsl:apply-templates/>
    </span>
  </xsl:template>
</xsl:transform>

转换的不良结果是:

<p>My text uses <span>highlighting</span> methods</p>
<p>Next line uses <span>two </span>
   <span>highlighter</span> elements...</p>

<p> 中的第二个 <span> 产生一个换行符,这不是我想要的。

这种行为的原因是什么以及如何避免它,意思是:如何实现这种结果:

<p>My text uses <span>highlighting</span> methods</p>
<p>Next line uses <span>two </span><span>highlighter</span> elements...</p>

(是的,我需要<xsl:output indent="yes">,转换方法必须是"xml"。)

我能看到用你在问题最后一行指定的约束(method="xml"indent="yes")解决这个问题的唯一方法是将 xml:space="preserve" 添加到p 个您创建的元素,如

Whitespace characters MUST NOT be inserted in a part of the result document that is controlled by an xml:space attribute with value preserve.

(Source)

<?xml version="1.0" encoding="utf-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output indent="yes" method="xml"/>

  <xsl:template match="line">
    <p xml:space="preserve"><xsl:apply-templates/></p>
  </xsl:template>

  <xsl:template match="hi">
    <span>
      <xsl:apply-templates/>
    </span>
  </xsl:template>
</xsl:transform>

请注意,由于 xml:space="preserve",您还必须删除 p 元素和子元素 xsl:apply-templates 的开始和结束标记之间的白色 space。当 运行 使用 Saxon 9 HE 在您的示例输入上产生输出

<?xml version="1.0" encoding="UTF-8"?>
<p xml:space="preserve">My text uses <span>highlighting</span> methods</p>
<p xml:space="preserve">Next line uses <span>two </span><span>highlighter</span> elements...</p>

如果您可以改用 xhtml 输出方法(和 XHTML 名称space),则不允许 XHTML 缩进器在开始或结束元素的标签周围添加 space XHTML 指定为 "inline" 标记,这包括 span.

<?xml version="1.0" encoding="utf-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
               xmlns="http://www.w3.org/1999/xhtml">
  <xsl:output indent="yes" method="xhtml"/>

  <xsl:template match="/">
    <html><body><xsl:apply-templates/></body></html>
  </xsl:template>

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

  <xsl:template match="hi">
    <span>
      <xsl:apply-templates/>
    </span>
  </xsl:template>
</xsl:transform>

当 运行 对同一输入产生

<?xml version="1.0" encoding="UTF-8"?><html xmlns="http://www.w3.org/1999/xhtml">
   <body>

      <p>My text uses <span>highlighting</span> methods
      </p>

      <p>Next line uses <span>two </span><span>highlighter</span> elements...
      </p>

   </body>
</html>

两个 span 元素之间没有 space。