简体   繁体   中英

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. 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. 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. Unfortunately, in the CMS of choice, typo3, I just can use a XSLT 1.0 processor.

result.xml

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

mycore_1.xml

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

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.

<!-- 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. Is there a way to replace the input to allow for sorting and formatting the dmdSec element and subelements?

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.

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

<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

<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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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