如何使用已删除的源元素漂亮地打印 XSLT 结果文档? [英] How do I pretty print an XSLT result document with removed source elements?

查看:17
本文介绍了如何使用已删除的源元素漂亮地打印 XSLT 结果文档?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个源 XHTML 文档,其中包含多个命名空间中的元素,我正在将其转换为 HTML 文档(显然没有命名空间).在我的 XSL 模板中,我只匹配 XHTML 命名空间中的元素以从结果树中删除非 HTML 兼容的元素.然而,在输出中,虽然这些元素消失了,但我用来缩进它们的空格仍然存在——即不相关的 CR/LF 和制表符行.

例如,如果这是我的输入:

<svg:svg><img/></svg:foreignObject></svg:svg>

应用转换后,这将是输出:

<img/>

虽然我的期望输出是这样的:

<img/>

使用 TransforMiiX(在 Firefox 中本地附加样式表)和 libxslt(使用 PHP 在服务器端附加样式表)都会发生这种情况,所以我知道这可能是某些 XSL 参数未设置的结果,但我试过玩与 <xsl:output indent="yes|no"/>, xml:space="default|preserve", <xsl:strip-space elements="foo bar|*"/>,都无济于事.

这将在服务器端实现,所以如果没有办法在原始 XSL 中实现,但有办法在 PHP 中实现,我会接受.

我知道这不是命名空间问题,因为删除任何元素都会得到相同的结果.

解决方案

您看到的空白区域来自源文档.XSLT 默认规则说应该复制文本节点,它们是否为空都没有关系.要覆盖默认规则,请包括:

或者:发现任何 (或 ) 并明确指定要应用模板的 个孩子.如果您的转换部分依赖于身份模板(在这种情况下,文本节点的空模板会适得其反),则此方法可能是必要的.

我已经按照 Word 的方式在您的代码段中标记了无关紧要"的空白:

¶····¶··········¶············¶··········</svg:foreignObject>¶····</svg:svg>¶

您还可以像这样修改您的身份模板:

<xsl:copy><!-- 选择除空白文本节点之外的所有内容--><xsl:apply-templates select="node()[not(self::text())] |text()[normalize-space() != ''] |@*"/></xsl:copy></xsl:模板>

这将删除任何空白文本节点(属性值保持不变,它们不是文本节点).使用 <xsl:output indent="yes"/> 漂亮地打印结果.

I have a source XHTML document with elements in multiple namespaces that I am transforming into an HTML document (obviously with no namespaces). In my XSL templates I only match elements in the XHTML namespace to remove non-HTML-compatible elements from the result tree. However, in the output, while those elements are gone, the whitespace I used to indent them remains—i.e., lines of irrelevant CR/LFs and tabs.

For example, if this is my input:

<div id="container">
    <svg:svg>
        <svg:foreignObject>
            <img />
        </svg:foreignObject>
    </svg:svg>
</div>

After applying the transformation, this will be the output:

<div id="container">


            <img />


</div>

While my desired output is this:

<div id="container">
    <img />
</div>

This happens using both TransforMiiX (attaching the stylesheet locally in Firefox) and libxslt (attaching the stylesheet server-side with PHP), so I know it's probably the result of some XSL parameter not getting set, but I've tried playing with <xsl:output indent="yes|no" />, xml:space="default|preserve", <xsl:strip-space elements="foo bar|*" />, all to no avail.

This will be implemented server-side so if there's no way to do it in raw XSL but there is a way to do it in PHP I'll accept that.

I know this is not a namespace issue since I get the same result if I remove ANY element.

解决方案

The white space you see is from the source document. XSLT default rules say that text nodes should be copied, it does not matter if they are empty or not. To override the default rule, include:

<xsl:template match="text()" />

Alternatively: Spot any <xsl:apply-templates /> (or <xsl:apply-templates select="node()" />) and explicitly specify which children you want to apply templates to. This method might be necessary if your transformation partly relies on the identity template (in which case the empty template for text nodes would be counter-productive).

I have marked up the "insignificant" white space in your snippet the way Word would do it:

<div id="container">¶
····<svg:svg>¶
········<svg:foreignObject>¶
············<img />¶
········</svg:foreignObject>¶
····</svg:svg>¶
</div>

EDIT: You can also modify your identity template like this:

<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>

This would remove any blank-only text node (attribute values remain untouched, they are not text nodes). Use <xsl:output indent="yes" /> to pretty-print the result.

这篇关于如何使用已删除的源元素漂亮地打印 XSLT 结果文档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆