简体   繁体   English

xslt 1.0:对多个文档中的元素进行排序

[英]xslt 1.0: sorting elements across multiple documents

I have a search result in an xml documents (called result.xml) as a list of references to container documents (mycore.xml) which refer to the "real" content file (mets.xml) in a another document. 我在xml文档(称为result.xml)中有一个搜索结果,作为对容器文档(mycore.xml)的引用列表,这些文档引用了另一个文档中的“真实”内容文件(mets.xml)。 The problem arrises when not only to format the third level document but sort the whole result based on an element on the third level document (the year of the publication dataIssued) in the mets.xml document. 问题不仅仅在于格式化第三级文档,还在于根据mets.xml文档中第三级文档(发布数据的发布年份)上的元素对整个结果进行排序。 Here a rough picture of that: 这是一个大概的图片:

/result/doc/@href --> document('mycore_1.xml')/mycore/file/@href -> document('mets_1.xml')/mets/dmdSec
       /doc/@href --> document('mycore_2.xml')/mycore/file/@href -> document('mets_2.xml')/mets/dmdSec

I have a solution using a XSLT 2.0 function but didn't got that working using call or apply template in XSLT 1.0. 我有一个使用XSLT 2.0函数的解决方案,但在XSLT 1.0中使用调用或应用模板无法正常工作。 Unfortunately, in the CMS of choice, typo3, I just can use a XSLT 1.0 processor. 不幸的是,在选择的CMS中,Typo3,我只能使用XSLT 1.0处理器。

result.xml 为result.xml

<result>
  <doc href="mycore_1.xml"/>
  <doc href="mycore_2"/>
  ...
</result>

mycore_1.xml mycore_1.xml

<mycore>
  <file href="mets_1.xml">
</mycore>

mets_1.xml mets_1.xml

<mets>
  <dmdSec>
    <mods>
      <dataIssued>1980
      </dateIssued>
      <namePart>Jones
      </namePart>
       ...
    </mods>
  </dmdSec>
</mets>

Here is for XSLT 2.0 a function definition that works for me. 这是适用于XSLT 2.0的函数定义。

<!-- returns a node-set of all dmdSec -->
<xsl:function name="mets:fetchFiles">
  <xsl:param name="docs"/>
  <xsl:for-each select="$docs">
    <xsl:for-each select="document(@href)/mycore/file">
       <xsl:for-each select="document(@href)/mets/dmdSec">
         <xsl:copy-of select="."/>
       </xsl:for-each>
    </xsl:for-each>
  </xsl:for-each>
</xsl:function>

And here the call and sorting: 这里是调用和排序:

<xsl:for-each select="fetchFiles(result/doc)">
  <xsl:sort select="mods/dateIssued"/>
  <xsl:call-template name="theFormatting">
  ... <!-- format and output the dmdSec/mods -->
  </xsl:call-template>
</xsl:for-each>

The difficulty for me seems to be, that the copy-of in the function returns a modified input but with call-template I just produce with copy-of output. 对我来说,困难似乎是,该函数中的copy-of返回修改后的输入,但是使用调用模板,我只是使用copy-of输出生成。 Is there a way to replace the input to allow for sorting and formatting the dmdSec element and subelements? 有没有一种方法可以替换输入,以便对dmdSec元素和子元素进行排序和格式化?

Any response would be appreciated! 任何回应将不胜感激!

Holger 霍尔格

Well if you wanted to implement the XSLT 2.0 function in XSLT 1.0 you could do that as a template which would then return a result tree fragment you could convert into a node-set (with exsl:node-set($rtf) ) for sorting. 好吧,如果您想在XSLT 1.0中实现XSLT 2.0功能,则可以将其作为模板,然后返回结果树片段,您可以将其转换为节点集(使用exsl:node-set($rtf) )进行排序。

But frankly I don't see why you take all those steps, the document function is powerful enough to process several nodes and to return several documents so you should be able to use 但坦率地说,我不明白为什么要执行所有这些步骤, document功能强大到足以处理多个节点并返回多个文档,因此您应该能够使用

<xsl:for-each select="document(document(result/doc/@href)/mycore/file/@href)/mets/dmdSec">
  <xsl:sort select="mods/dateIssued"/>
  ...
</xsl:for-each>

respectively I would prefer to and suggest to use apply-templates eg 我分别希望并建议使用apply-templates例如

<xsl:apply-templates select="document(document(result/doc/@href)/mycore/file/@href)/mets/dmdSec">
  <xsl:sort select="mods/dateIssued"/>
</xsl:apply-templates>

and have 并有

<xsl:template match="mets/dmdSec">
  ...
</xsl:template>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM