2

我有一个大型 XSLT 样式表,可以将 XML 格式转换为 HTML。我想在输入 XML 文件中添加对 XInclude 的支持。目标是每个包含文件以及包含 XML 文件都可以独立进行 XSD 验证。我控制了 XML 模式中的所有更改(我认为);只有特定的 XML 元素可以移出到包含文件中,并且只有一层包含文件嵌套。我在 Eclipse 的 XML 编辑器中工作,它很好地验证了包含文件和每个包含文件。

XSLT 样式表有两种使用方式,在这里我们更接近我的问题:

  1. 在使用 lxml 进行 XSLT 转换的 Python 脚本的构建环境中。Python 脚本被集成到基于 make 的构建环境和 Eclipse 的 Ant 脚本中。

  2. 在包含 XML 文件的 xsl-stylesheet 指令中。这适用于人们希望在 Web 浏览器中立即查看他们对任何 XML 文件所做的更改的情况。到目前为止,这已被证明是一个非常有效的环境,所以我不想放弃它。

我能够使用 Python 脚本中的 ElementTree.xinclude() 方法获得用例 1。但是,这不是用例 2 的解决方案。

另外,我确实了解如何编写只执行 Xinclude 解析的 XSLT 样式表,理论上这可以用作第一个转换,然后是现有的 XSLT 样式表,用于 XML 到 HTML 的转换。问题是 XML 文件只能有一个 xsl-stylesheet 指令。

另一个想法是将 XInclude 分辨率留给 Web 浏览器。但是,我不知道有任何 Web 浏览器支持该功能。另外,我不希望限制只使用一种特定的浏览器。到目前为止,我们支持所有最常见的浏览器。

另一个想法是将 XInclude 解析支持添加到现有的 XSLT 样式表中。但是,我在为输入和输出而苦苦挣扎,因为这实际上是三个阶段(文件中的 XML 输入 -> 带有 Xinclude 解析的 FLat XML -> HTML。XInclude 解析部分需要执行第一次转换而现有的 XSLT 代码将执行第二个。我不确定这在一个样式表中是否可行。

我的问题是:

  1. 有什么方法可以在使用 Web 浏览器打开(包括)XML 文件时调用两个 XSLT 样式表?

  2. 有什么方法可以改进现有的 XSLT 样式表并支持 XInclude 以使其保持单个样式表?

  3. XSLT 样式表中有什么方法可以修改输入吗?

  4. Web 浏览器是否对 XInclude 分辨率提供任何支持?

谢谢安迪

4

2 回答 2

2

1有什么方法可以在使用 Web 浏览器打开(包括)XML 文件时调用两个 XSLT 样式表?

2有什么方法可以改进现有的 XSLT 样式表并支持 XInclude 以使其保持单一样式表?

[3] XSLT 样式表中是否有任何方法可以修改输入?

[4] Web 浏览器是否支持 XInclude 解析?

以相反的顺序处理问题,因为这样更容易:

(4) 我也没有看到任何做 XInclude 扩展的网络浏览器。

(3) 我不知道“修改输入”是什么意思:XSLT 将输入转换(或修改)为输出。除非您要问:您可以一步修改输入,然后再次转换输出吗?是的:如果浏览器支持 exslt:node-set,那么您可以使用一次转换的结果创建一个变量,然后选择该变量进行另一次转换。您可以使用模式为不同的步骤选择一组不同的模板。

就像是:

 <xsl:variable name="doc.all">
    <xsl:apply-templates  mode="p1" select="/" />
</xsl:variable>

使用一组 mode="p1" 模板,以及在某处选择该变量作为节点集的模板:

  <xsl:template match="/" >
    <xsl:apply-templates select="exslt:node-set($doc.all)" />
  </xsl:template>

[ XSLT-2.0 可以更直接地处理节点集,但是没有浏览器本身支持 XSLT-2.0 ]

(2) 我不知道您现有的样式表是什么样的,但可能:是的。当您认为执行 XInclude 处理和 xslt 的其余部分必须是两个单独的步骤时,您是在程序上思考。如果您使用 XSLT 进行 XInclude 扩展,那么 xinclude 只是要匹配的另一组模式。

您可能需要类似此模板的内容来执行 xinclude 扩展:

   <xsl:template   match="xi:include[@href][@parse='xml' or not(@parse)]">
        <xsl:apply-templates select="document(@href)/*" />  
    </xsl:template>

从这个问题的答案修改:在文档(@href)之后添加“/ *”以避免在包含的文档以及基础文档上再次调用根模板。

然后包含一个 match="/" 模板来设置外部 html,其余的转换模式来创建内部节点。

这两个步骤在这里是隐含的:第一步是在遇到该元素时将输入源重定向到 xi:include/@href。步骤是根据其他匹配模板处理该文档中的节点。

(1) 使用 PI 只能运行一个样式表,但是,您的浏览器中有 Javascript,所以只要避免跨域安全问题,您应该可以按程序进行操作。

需要考虑的几点:

我不知道如果作为一次转换的结果,您生成另一个具有不同指令的文件,浏览器会做什么。它又继续了吗?可能值得一试。如果没有,您可以在 javascript 中显式进行处理,然后应用第二次转换。

您在浏览器中支持 xslt、javascript 和 css:您可以将 javascript 和 css 注入到输出中。css 可以为 XML 和 HTML 设置样式。

Michael Kay 发布了Saxon CE,这是一个编译成 javascript 的 XSLT 2.0 实现,因此它可以在浏览器中运行。

于 2013-08-10T07:53:24.320 回答
0

您可能应该看看 XProc 来做到这一点

看来您的用例过于复杂,无法在单个 XSLT 中完成

于 2013-03-23T11:56:45.297 回答