检查/解决单独的xml文件中的交叉引用

时间:2016-09-23 09:44:26

标签: xml xslt xslt-2.0

起点

假设我们有一本xml格式的书。本书由许多资产组成,这些资源可以通过带有属性ref-asset的标记path相互引用。 [路径掩码:目标资产的 {id} | {version}

重要说明:资产是单个文件,没有合并的完整文件。

示例性XML (合并以获得更好的视觉效果)

<book>
    <!-- file a.xml -->
    <asset id="1" version="1.0">
        <name>Prolog</name>
    </asset>
    <!-- file b.xml -->
    <asset id="2" version="2">
        <name>Table of content</name>
        <list>
            <item><ref-asset path="1|1.0">Prolog</ref-asset></item>
            <item><ref-asset path="2|2.0">Table of content</ref-asset></item>
            <item><ref-asset path="3|1.1">FooBar</ref-asset></item>
        </list>
    </asset>
    <!-- file c.xml -->
    <asset id="3" version="1.1">
        <name>FooBar</name>
    </asset>
</book>

请求

  • 如果关联目标位于ref-asset
  • ,请检查所有book
  • 创建有关结果的报告[存在,不存在,资产存在但版本错误,...]
  • [另外:用目标内容替换引用。]

设置

  • Saxon 9.6.x EE XSLT 2.0
  • 爪哇
  • 100到1000个单个文档(组合文件大小:高3位Mb)

如何解决

首次尝试功能XML-RPC-Server example +功能collection()

通过集合()搜索文件系统上的所有单个资产文件,通过document()将其加载到进程中并搜索匹配的匹配。

第二次尝试合并,完成文件:

将所有单assets合并到book并通过xsl:key或类似技术进行匹配。

问题(S)

  • collection()是否能够加载数千个文档,并且仍然可以使用后续document()来处理资产?
  • 如何“索引”运行时加载的文档[仍然通过xsl:key?]进行有效搜索?

进一步的提示非常受欢迎/不需要特定的样式表[我会自己做,只要我知道要走的路]。

编辑:collection()已经返回一系列文档节点,因此可能不需要document()

1 个答案:

答案 0 :(得分:2)

关于表现的问题总是依赖于产品,因此如果问题是特定于撒克逊人的,那么回答会更容易。

我经常在Saxon中使用collection()函数来处理数千个输入文档,是的,它完全有能力做到这一点。在Saxon-EE中,collection()是多线程的,因此您可以在多核机器上并行解析多个文档。

索引有点棘手,因为key()函数只能搜索一个文档。我们在几周前在Oxford XML Summer School的性能研讨会上研究了一个非常类似的问题,并通过使用新的XSLT 3.0地图功能解决了这个问题(加速了十倍)。像这样:

<xsl:variable name="index" as="map(xs:string, element(asset))">
  <xsl:map>
    <xsl:for-each select="collection('....')/asset">
      <xsl:map-entry key="@id || '|' || @version"
                     select="."/>
    </xsl:for-each>
  </xsl:map>
</xsl:variable>

<xsl:template match="ref-asset">
  <xsl:variable name="asset" select="$index(@path)"/>
  ....
</xsl:template>