XSLT 呈现 HTML br 标签不一致

XSLT Rendering HTML br tags inconsistently

我在应用正在呈现的 XSL 时观察到不一致的行为 html。我的具体问题在下面的代码块之后。

XML 实例:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <element1>
        <child2>XXXXXX</child2>
    </element1>
</root>

我的简单 XSLT

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

  <xsl:output method="html"/>

  <xsl:template match="/">
  <html  xmlns="http://www.w3.org/1999/xhtml">
      <head>
        <title>Test Instance</title>
      </head>   
      <body>
        <xsl:value-of select="/root/element1/child2"/>
        <br/>
        NBSP = '&#160;'
        <br/>
        <xsl:apply-templates select="//element1"/>
      </body>
  </html>
  </xsl:template>    

  <xsl:template match="//element1">
      Call From Template:
      <br/>
      <xsl:value-of select="./child2"/>
      <br/>
  </xsl:template>
</xsl:stylesheet>

我的结果输出

<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <title>Test Instance</title>
   </head>
   <body>XXXXXX<br></br>
                NBSP = '&nbsp;'
                <br></br>
            Call From Template:
            <br xmlns="">XXXXXX<br xmlns=""></body>
</html>

所以我的两个具体问题如下:

  1. 根模板渲染的'br'标签一致 在渲染输出中被关闭,而那些从应用转换中渲染的则不是。我对它应该呈现的方式的理解是所有 'br' 标签都将保持打开状态。 谁能解释为什么会这样? 如果我将输出方法更改为 'xhtml' 与 saxon he 9.0.3.5 或 'xml' 与任何其他解析器,它呈现 'br' 通过关闭所有标记来始终如一地标记。
  2. 我的第二个问题与插入到 html 输出中的非阻塞 space ( ) 的处理有关。当呈现为输出并使用默认的 UTF-8 编码时,它会使用   显式显示不间断的 space,同时将输出指定为 xhtml 或xml 导致 space 呈现为 C2 A0,这是非中断 space 的 UTF-8 表示。是否有任何关于为什么将其呈现为 xhtml 而不是 html 的 UTF-8 的想法?虽然我猜测这是因为 xhtml 应该与 html 进行解析的方式有关,但我发现某些 xhtml 解析器(特别是 iText XMLWorker) 没有正确解码表示为 UTF-8 代码的非中断 space,我正在尝试找出解决方法。

谢谢

XSLT 2.0,html 输出

<xsl:transform
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

<xsl:output method="html" version="5" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:template match="/">
  <html>
      <head>
        <title>Test Instance</title>
      </head>   
      <body>
        <xsl:value-of select="/root/element1/child2" />
        <br/>
        NBSP = '&#160;'
        <br/>
        <xsl:apply-templates select="//element1" />
      </body>
  </html>
</xsl:template>

<xsl:template match="//element1">
  Call From Template:
  <br />
  <xsl:value-of select="./child2" />
  <br />
</xsl:template>

</xsl:transform>

XSLT 2.0, xhtml 输出,强制   (不是个好主意)

<xsl:transform
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

<xsl:output method="xhtml" encoding="UTF-8" indent="yes" use-character-maps="a" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />

<xsl:character-map name="a">
  <xsl:output-character character="&#160;" string="&amp;nbsp;"/>
</xsl:character-map>

<xsl:template match="/">
  <html>
      <head>
        <title>Test Instance</title>
      </head>   
      <body>
        <xsl:value-of select="/root/element1/child2" />
        <br/>
        NBSP = '&#160;'
        <br/>
        <xsl:apply-templates select="//element1" />
      </body>
  </html>
</xsl:template>

<xsl:template match="//element1">
  Call From Template:
  <br />
  <xsl:value-of select="./child2" />
  <br />
</xsl:template>

</xsl:transform>

XSLT 2.0,xhtml 输出,正确的方式

<xsl:transform
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

<xsl:output method="xhtml" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />

<xsl:template match="/">
  <html>
      <head>
        <title>Test Instance</title>
      </head>   
      <body>
        <xsl:value-of select="/root/element1/child2" />
        <br/>
        NBSP = '&#160;'
        <br/>
        <xsl:apply-templates select="//element1" />
      </body>
  </html>
</xsl:template>

<xsl:template match="//element1">
  Call From Template:
  <br />
  <xsl:value-of select="./child2" />
  <br />
</xsl:template>

</xsl:transform>

XSLT 1.0,xhtml 输出

<xsl:transform
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/1999/xhtml"
    version="1.0">

<xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />

<xsl:template match="/">
  <html>
      <head>
        <title>Test Instance</title>
      </head>   
      <body>
        <xsl:value-of select="/root/element1/child2" />
        <br/>
        NBSP = '&#160;'
        <br/>
        <xsl:apply-templates select="//element1" />
      </body>
  </html>
</xsl:template>

<xsl:template match="//element1">
  Call From Template:
  <br />
  <xsl:value-of select="./child2" />
  <br />
</xsl:template>

</xsl:transform>

使用 HTML 输出方法,仅当 br 元素不在任何命名空间中时才会对其进行特殊处理(呈现为 <br>)。

使用 XHTML 输出方法,br 元素只有在 XHTML 命名空间中才会被特殊处理(呈现为 <br />)。

XSLT 3.0 支持 method="html" version="5",其中 "no namespace" 和 "XHTML namespace" 都被接受。