【问题标题】:XSLT ignoring   during transformationXSLT 在转换期间忽略
【发布时间】:2018-03-03 02:28:24
【问题描述】:

我有一个 HTML 文件,我用 XSL 将其转换为另一个 HTML 文件(只是调整它的结构,使其在大多数电子邮件客户端中看起来不错)。

HTML 是从其他系统接收的,我无法修改此 HTML 的生成方式。


我的问题是标签内部包含 。 XSL 转换忽略它。

HTML 输入:

<span style="font-family: 'HelveticaNeue LT 45 Lt', serif; font-size: 12px; color:#000000">
  IMPORTANT: The loan is repayable by 10 payments.&nbsp;The first Direct Debit payment will be collected&nbsp;along with other payments that are already due&nbsp;on...
</span>

HTML 输出:

<p class="bodytext" align="justify" style="font-size:14px; font-weight:200; font-align:justify;">
  IMPORTANT: The loan is repayable by 10 payments.The first Direct Debit payment will be collectedalong with any other payments that are already dueon...
</p>

两个空格都缺失,文本被连接:payments.Thedueon


XSL 有点复杂。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:character-map name="escape">    
  <xsl:output-character character="&#128;" string="&amp;euro;"/>    
  <xsl:output-character character="&#160;" string="&amp;nbsp;"/>
</xsl:character-map>
<xsl:output method="html" indent="yes" use-character-maps="escape"/>
<xsl:template match="body">
 <html>        
   <head>
    <meta name="generator" content="HTML EMail optimization by" />          
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
...

...
<xsl:template name="TextTemplate">
 <xsl:if test="not(starts-with(.,'XSLTButton'))">
  <xsl:value-of select="text()"/>          
 </xsl:if>
</xsl:template>

我正在使用 Saxon 9.1.0.8

经过一番谷歌搜索后,我尝试使用 xsl:character-map,xsl:preserve-space,更改编码.. 但没有任何效果。

唯一有效的方法是将[&lt;!ENTITY nbsp "&amp;#160;"&gt;] 声明添加到 INPUT html 中的 DOCTYPE,但我不想在此过程中创建额外的步骤来添加此位。

请帮忙。我应该添加什么让 XSL/Saxon 停止忽略 &amp;nbsp;

【问题讨论】:

  • 你是如何运行这个转换的? Saxon 接受来自 XML 解析器的输入,并且 XML 解析器的工作是处理实体引用,例如 &npsp;。如果没有带有实体声明的 DTD,标准 XML 解析器将拒绝此类实体引用,在您的场景中似乎就是这种情况。由于在这种情况下,解析器似乎是在剥离实体引用而不是拒绝它,所以我们需要知道您是如何运行转换的,特别是您正在使用什么 XML 解析器以及它是如何配置的。
  • 为了更直接地回答这个问题,如果您不想让 Saxon 忽略 &amp;nbsp;,那么您必须以某种方式确保 XML 解析器告诉 Saxon 它在那里......
  • 感谢您的评论,它引导我走向正确的方向。我们正在运行这样的转换:java -cp %BASEDIR%\lib\* -Dxml.catalog.files=%BASEDIR%\conf\catalog.xml net.sf.saxon.Transform -r:org.apache.xml.resolver.tools.CatalogResolver -x:org.apache.xml.resolver.tools.ResolvingXMLReader -y:org.apache.xml.resolver.tools.ResolvingXMLReader -o:%output% -s:%input% -xsl:file:%xsl% 感谢您在此处的注释,我找到了本地 DTD 文件并在其中添加了实体声明,其工作正常。

标签: html xml xslt saxon


【解决方案1】:

DTD 感知 XML 解析器要求声明文档所引用的实体。 XSLT 处理需要扩展实体引用,因此符合标准的 XSLT 处理器通常将符合 DTD 的 XML 解析器用于其前端。如果您继续提供使用未声明实体的处理输入,那么您将继续获得不满意的结果。

如果输入已经有一个文档类型声明并引用了适当的 DTD,那么您应该尝试使用 DTD-aware 解析器。如果没有,您可以注入这样的文档类型声明,或者您可以通过 Tidy 或类似的处理器运行 HTML,该处理器假定 HTML DTD 并扩展所有实体引用。

【讨论】:

  • 是的,输入 HTMl 有一个 Doctype 声明。 &lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt; 我们有 Resolver,它加载本地 DTD 而不是声明的 DTD,所以我在那里添加了 Entity 并且它可以工作(见我上面的评论)。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-11
  • 1970-01-01
  • 2022-01-11
  • 2017-10-01
  • 1970-01-01
  • 2017-06-23
相关资源
最近更新 更多