我有一个源 XHTML 文档,其中包含多个命名空间中的元素,我正在将其转换为 HTML 文档(显然没有命名空间)。在我的 XSL 模板中,我仅匹配 XHTML 命名空间中的元素,以从结果树中删除不兼容 HTML 的元素。然而,在输出中,虽然这些元素消失了,但我用来缩进它们的空格仍然存在,即不相关的 CR/LF 和制表符行。
例如,如果这是我的输入:
<div id="container">
<svg:svg>
<svg:foreignObject>
<img />
</svg:foreignObject>
</svg:svg>
</div>
应用转换后,输出如下:
<div id="container">
<img />
</div>
虽然我想要的输出是这样的:
<div id="container">
<img />
</div>
使用 TransforMiiX(在 Firefox 中本地附加样式表)和 libxslt(使用 PHP 在服务器端附加样式表)会发生这种情况,所以我知道这可能是某些 XSL 参数未设置的结果,但我尝试过玩与 <xsl:output indent="yes|no" />
, xml:space="default|preserve"
, <xsl:strip-space elements="foo bar|*" />
,一切都无济于事。
这将在服务器端实现,因此如果无法在原始 XSL 中实现,但有办法在 PHP 中实现,我会接受。
我知道这不是命名空间问题,因为如果删除任何元素,我都会得到相同的结果。
最佳答案
您看到的空白来自源文档。 XSLT 默认规则规定应复制文本节点,无论它们是否为空。要覆盖默认规则,请包括:
<xsl:template match="text()" />
或者:发现任何 <xsl:apply-templates />
(或 <xsl:apply-templates select="node()" />
)并明确指定要应用模板的子。如果您的转换部分依赖于身份模板,则可能需要此方法(在这种情况下,文本节点的空模板将产生反作用)。
我已经按照 Word 的方式标记了代码片段中“无关紧要”的空白:
<div id="container">¶
····<svg:svg>¶
········<svg:foreignObject>¶
············<img />¶
········</svg:foreignObject>¶
····</svg:svg>¶
</div>
编辑:您还可以像这样修改您的身份模板:
<xsl:template match="node() | @*">
<xsl:copy>
<!-- select everything except blank text nodes -->
<xsl:apply-templates select="
node()[not(self::text())] | text()[normalize-space() != ''] | @*
" />
</xsl:copy>
</xsl:template>
这将删除任何纯空白文本节点(属性值保持不变,它们不是文本节点)。使用<xsl:output indent="yes" />
漂亮地打印结果。
关于php - 如何漂亮地打印已删除源元素的 XSLT 结果文档?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2228004/