确定XSLT中“已使用”的所有xpath引用/ xml元素

时间:2013-02-08 10:41:50

标签: xml xslt xpath xslt-2.0

问题:

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

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

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

理想解决方案:

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

我意识到这可能没有一个简单的答案,但是如果有人在那之前做过这件事,或者可以给我一个起点,我会非常感谢任何帮助。

提前致谢!

3 个答案:

答案 0 :(得分:0)

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

我可以想到解决这个问题的两种方法;两者都非常有趣并且(在一般情况下)很多工作,在这种情况下值得,只有当减少XML的优势对你来说是值得的,或者如果你的特定情况变得非常容易比一般情况。

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

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

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

答案 1 :(得分: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。

答案 2 :(得分:0)

后期添加:此处描述的内容非常类似于&#34;文档投影&#34;这是一种可在许多XQuery处理器(包括Saxon)中使用的技术。 XQuery比XSLT更适合静态分析(因为它缺乏非常动态的模板发送机制)。

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

最初的理论描述如下:Amelie Marian,Jerome Simeon,2003,Projecting XML Documents,哥伦比亚大学学术共享,http://hdl.handle.net/10022/AC:P:29177