1

问题:

我们有一个庞大的 XML 文档。该文档在最终被用于 XSLT2 转换之前被传递了一点,该转换为在 PDF 渲染引擎中使用做准备。问题是当我们到达 PDF 渲染引擎时实际需要的 XML 百分比与其原始大小相比是很小的。我们仍然需要其他流程的完整 XML,但就流向渲染引擎的“流程”而言,我们希望尽快将 XML 剥离到其基本要素,以便传递的数据量是更小。

我们不能在此过程的早期进行最终的 XSLT2 转换,因为在此之前发生了更多的 XML 操作。

因此,我们想做的是创建一个新样式表,它简单地“保留”原始 XML 文档的结构,但只保留我们实际感兴趣的 XML 元素以用于报告目的。我们很高兴编写必要的 XSLT 文档,但由于最终的 XSLT2 文档是一个复杂的野兽,我们希望 stackoverflow 社区中的某个人能够轻松地执行以下操作:

理想的解决方案:

一种从现有 XSLT2 样式表中提取所有引用的 XML 元素(即它们的 xPath)列表的方法。我们希望这不仅包括在 selects/value-ofs/etc. 中,而且包括在 fors/conditions/etc 中的引用 XML 元素。

我意识到这可能没有一个简单的答案,但万一有人以前做过这个,或者可以给我一个起点,我将非常感谢任何帮助。

提前致谢!

4

3 回答 3

0

祝你好运。我不知道任何现成的解决方案。

我可以想到两种方法来解决这个问题;两者都将非常有趣并且(在一般情况下)需要大量工作,在这种情况下,只有当精简 XML 的优势对您来说非常值得时,或者如果您的特定情况证明要容易得多比一般情况。

  1. 您可以检测 XSLT 样式表,以便每次任何模板访问节点时,它都会记录该节点的身份(例如,以简单 XPointer 样式的从根的数字路径的形式,或者可能以完全限定的通用标识符(从文档元素开始到被访问的元素的元素名称序列)。然后,第二个样式表可以读取访问的节点列表并制作输入副本,将每个节点标记为已访问是否使用过。为足够的输入执行此操作,您将(可能)看到可用于精简 XML 的模式。为足够的输入执行此操作,您可以检查给定的精简过程是否会(a)错过有些东西它可能会掉,或者(b)掉一些它不应该掉的东西。

  2. 您可以尝试从样式表抽象地工作,从根元素的模板开始,并注意哪些可能的元素类将匹配哪些模板。如果您有一个好的输入词汇表模式并且可以假设该模式的有效性作为前提,这可能有助于您在这里推理。

这两个都非常具有挑战性——第二个看起来很像类型理论家试图做的那种事情,以使人们能够提前预测来自给定 XSLT 转换的输出对于特定输出是否有效,给定有效的输入。不幸的是,迄今为止对这项工作的简短总结似乎是“天哪,这很难!” 另一方面,您的任务比他们的任务简单一点:您只想知道,您能否通过查看转换提前知道 XML 文档中的特定分支永远不会影响转换的输出?而且您不必为一般情况解决它,您只需为一个特定的转换解决它。

于 2013-02-08T17:31:35.397 回答
0

您希望有一个 XSLT 样式表,它以与以前完全相同的结构将任何可用的内容复制到新文档中,只跳过那些被认为是多余的标签。

下面的样式表正是这样做的。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html"/>

    <xsl:template match="/">
       <html><textarea rows="20" cols="120">
       <xsl:apply-templates />
       </textarea></html>
    </xsl:template>

    <xsl:template match="*|@*">
       <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
       </xsl:copy>
    </xsl:template>

   <xsl:template match="removeElmt1|removeElmt2|@removeAttr1|@removeAttr2">
   <!-- do nothing :) -->
   </xsl:template>

</xsl:stylesheet>

说明:永远不要忘记 XSLT 不是一种编程语言,而是一种转换引擎的规范。

第一个模板指定开始该过程,第二个模板指定匹配所有内容,然后复制所有内容,第三个模板中指定的元素和属性除外。

注意:如果在文档中重用元素或属性,则在第三个模板的“匹配”规范中需要更具体的 Xpath 语句,以便仅删除指定的那些。

第一个模板包含两个冗余规范,以便在浏览器中读取结果。对于确切的副本,您需要删除<html><textarea>规范元素,并将输出方法设置为 XML。

于 2015-05-17T10:41:45.707 回答
0

一个较晚的补充:这里描述的内容听起来很像“文档投影”,这是一种可用于许多 XQuery 处理器(包括 Saxon)的技术。XQuery 比 XSLT 更适合静态分析(因为它缺乏非常动态的模板发送机制)。

文档投影将文档和查询作为输入,并生成一个文档作为输出,该文档仅包含原始文档中回答原始查询所需的那些部分。好处是文档投影过程是流式的——原始文档不需要在内存中构建;相反,投影过程充当来自 XML 解析器的事件的过滤器。

原始理论在此处描述:Amelie Marian, Jerome Simeon, 2003, Projecting XML Documents, Columbia University Academic Commons, http://hdl.handle.net/10022/AC:P:29177

于 2016-11-29T08:55:35.917 回答