XSLT 中的预处理

发布于 2024-08-14 16:07:56 字数 223 浏览 8 评论 0原文

是否可以在 XSLT 中进行“预处理”?

通过预处理,我的意思是更新源树的(在内存中的表示形式)。

这是可能的,还是我需要为其进行多次转换。

用例: 我们为我们的客户提供了 Docbook 参考手册,但对于某些客户来说,它们需要不同的“皮肤”(不同的图像等)。所以我希望做的是根据参数转换图像 fileref 路径。然后应用其余的常规 Docbook XSL 模板。

is it at all possible to 'pre-proccess' in XSLT?

with preprocessing i mean updating the (in memory representation) of the source tree.

is this possible, or do i need to do multiple transforms for it.

use case:
we have Docbook reference manuals for out clients but for certain clients these need different 'skins' (different images etc). so what i was hoping to do is transform the image fileref path depending on a parameter. then apply the rest of the normal Docbook XSL templates.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

忘年祭陌 2024-08-21 16:07:57

扩展 Eamon 的答案...

对于 XSLT 1.0 或 2.0,您首先将中间(预处理)结果放入中。元素,全局(顶级)或本地(模板内)声明。

<xsl:variable name="intermediate-result">
  <!-- code to create pre-processed result, e.g.: -->
  <xsl:apply-templates mode="pre-process"/>
</xsl:variable>

在 XSLT 2.0 中,$intermediate-result 变量的值是由一个文档节点(在 XSLT/XPath 1.0 中称为“根节点”)组成的节点序列。您可以像访问任何其他变量一样访问和使用它,例如 select="$intermediate-result/doc"

但在 XSLT 1.0 中,$intermediate-result 变量的值不是一流的节点集。相反,它是所谓的“结果树片段”。它的行为类似于包含一个根节点的节点集,但您使用它的方式受到限制。您可以复制它并获取其字符串值,但无法使用 XPath 向下钻取,如 select="$intermediate-result/doc" 中所示。为此,您必须首先使用处理器的 node-set() 扩展函数将其转换为一流的节点集。在 Saxon 6.5、libxslt 和 4xslt 中,您可以使用 exsl:node-set() (如 Eamon 的答案)。在 MSXML 中,您需要使用 msxsl:node-set(),其中 xmlns:msxsl="urn:schemas-microsoft-com:xslt",在 Xalan 中,我相信它被称为 xalan:nodeset() (没有连字符,但您必须通过 Google 查找名称空间 URI)。例如: select="exsl:node-set($intermediate-result)/doc"

XSLT 2.0 简单地废除了结果树片段,使得 node-set() 变得不必要。

Expanding on Eamon's answer...

In the case of either XSLT 1.0 or 2.0, you'd start by putting the intermediate (pre-processed) result in an <xsl:variable> element, declared either globally (top-level) or locally (inside a template).

<xsl:variable name="intermediate-result">
  <!-- code to create pre-processed result, e.g.: -->
  <xsl:apply-templates mode="pre-process"/>
</xsl:variable>

In XSLT 2.0, the value of the $intermediate-result variable is a node sequence consisting of one document node (was called "root node" in XSLT/XPath 1.0). You can access and use it just as you would any other variable, e.g., select="$intermediate-result/doc"

But in XSLT 1.0, the value of the $intermediate-result variable is not a first-class node-set. Instead, it's something called a "result tree fragment". It behaves like a node-set containing one root node, but you're restricted in how you can use it. You can copy it and get its string-value, but you can't drill down using XPath, as in select="$intermediate-result/doc". To do that, you must first convert it to a first-class node-set using your processor's node-set() extension function. In Saxon 6.5, libxslt, and 4xslt, you can use exsl:node-set() (as in Eamon's answer). In MSXML, you'd need to use msxsl:node-set(), where xmlns:msxsl="urn:schemas-microsoft-com:xslt", and in Xalan, I believe it's called xalan:nodeset() (without the hyphen, but you'll have to Google for the namespace URI). For example: select="exsl:node-set($intermediate-result)/doc"

XSLT 2.0 simply abolished the result tree fragment, making node-set() unnecessary.

卸妝后依然美 2024-08-21 16:07:57

这对于符合标准的 XSLT 1.0 来说是不可能的。然而,在我使用过的每个实际实现中都是可能的。然而,执行此操作的扩展因引擎而异。在标准 XSLT 2.0 中也是可能的(无论如何,它更容易使用 - 所以如果可以的话,就使用它)。

如果您的 xslt 处理器支持 EXSLT,则 exsl:node-set() 函数可以满足您的需求。 msxml 也有一个相同名称的扩展函数(但使用不同的命名空间 uri,不幸的是,这些函数并不完全兼容)。

This is not possible with standards compliant XSLT 1.0. It is possible in every actual implementation I've used, however. The extensions with which to do that differ by engine, however. It is also possible in standard XSLT 2.0 (which is in any case much easier to work with - so if you can, just use that).

If your xslt processor supports EXSLT, the exsl:node-set() function does what you're looking for. msxml has an identically named extension function as well (but with a different namespace uri, the functions are unfortunately not trivially compatible).

坏尐絯 2024-08-21 16:07:57

由于您尝试从同一 DocBook XML 源生成略有不同的输出,因此您可能需要研究 DocBook XSL 样式表中的“分析”(条件标记)支持。请参阅 第 26 章 /docbookxsl/" rel="nofollow noreferrer">DocBook XSL:完整指南作者:Bob Stayton:

分析是 DocBook 中使用的术语
描述条件文本。
条件文本意味着您可以创建
一个包含一些内容的 XML 文档
标记为条件的元素。什么时候
你处理这样一个文档,你可以
指定适用哪些条件
该版本的输出以及
样式表将包含或排除
标记文本以满足条件。
当你需要的时候这个功能很有用
生产一个以上版本
文档,版本不同
小方法。

例如,要对同一文档的 Windows 和 Mac 版本使用不同的图像,您可能有一个如下所示的 DocBook XML 片段:

<figure>
  <title>The Foo dialog</title>
  <mediaobject>
    <imageobject os="windows">
      <imagedata fileref="screenshots/windows/foo.png"/>
    </imageobject>
    <imageobject os="mac">
      <imagedata fileref="screenshots/mac/foo.png"/>
    </imageobject>
  </mediaobject>
</figure>

然后,您将使用 DocBook XSL 样式表的支持分析的版本以及 profile.os 参数设置为 windowsmac

Since you are trying to generate slightly different output from the same DocBook XML source, you might want to look into the "profiling" (conditional markup) support in DocBook XSL stylesheets. See Chapter 26 in DocBook XSL: The Complete Guide by Bob Stayton:

Profiling is the term used in DocBook
to describe conditional text.
Conditional text means you can create
a single XML document with some
elements marked as conditional. When
you process such a document, you can
specify which conditions apply for
that version of output, and the
stylesheet will include or exclude the
marked text to satisfy the conditions.
This feature is useful when you need
to produce more than one version of a
document, and the versions differ in
minor ways.

For example, to use different images for, say, Windows and Mac versions of the same document, you might have a DocBook XML fragment like this:

<figure>
  <title>The Foo dialog</title>
  <mediaobject>
    <imageobject os="windows">
      <imagedata fileref="screenshots/windows/foo.png"/>
    </imageobject>
    <imageobject os="mac">
      <imagedata fileref="screenshots/mac/foo.png"/>
    </imageobject>
  </mediaobject>
</figure>

Then, you would use the profiling-enabled versions of the DocBook XSL stylesheets with the profile.os parameter set to windows or mac.

断爱 2024-08-21 16:07:57

也许您应该在这里使用 XSLT“OOP”方法。将所有客户端的所有通用模板放入样式表中,并为每个客户端创建一个样式表,其中特定模板覆盖通用模板。使用 xsl:import 将公共样式表导入到特定样式表中,您只需调用与客户端对应的样式表即可进行一次处理。

Maybe you should use XSLT "OOP" methods here. Put all the common templates to all clients in a stylesheet, and create an stylesheet for each client with specific templates overriding common ones. Import the common stylesheet within the specific ones with xsl:import, and you'll do only one processing by calling the stylesheet corresponding to a client.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文