0
votes

I'm working with XML files (TEI XML, to be specific) produced as an export from an company-internal desktop application, let's call it the Editor. We use the Editor to produced digital editions of ancient texts; we enter/type/copy+paste the text itself and, using special text blocks within the Editor text, we also enter within that text various additional information, most pertinently:

  • edition references
  • synchronization marks
  • apparatus (= footnotes)

The general structure of the output XML is quite simple (minus namespaces):

<body>
<p>
text text text text text text
</p>
</body>

The additional information then appears in the appropriate place within the text as XML elements, namely:

  • edition references: <emph id="11.1">11.1</emph> or <note place="left">Bad. 41</note>
  • synchronization marks: <anchor type="sync2"/>
  • apparatus (= footnotes): <seg xml:id="wXX">someword</seg>

So for example:

<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, <anchor type="sync2"/>sed do <emph id="11.1">11.1</emph>eiusmod <seg xml:id="wXX">tempor</seg> incididunt
</p>

The problem is that the Editor was originally designed to produce beautiful PDFs where each of these would appear in a specific place on a page, so their order in the Editor does not matter; consequently, they are also exported in a more or less random order in the XML file.

This is not a problem for the XML structure, since they are all children of <p> and siblings. But it does pose problems when I transform the XML to HTML to be used online: everything is ok whenever there is text between them. But whenever they (at least two of them) meet / follow one another / are immediate siblings, they must appear in a particular order with regard to each other, namely <emph>/<note> > <sync> > <seg>.

My question is, can I achieve this, i.e. reorder those elements in question whenever necessary, using just XSLT (1.0 or 2.0)?

Thank you for any advice you may have.

1

1 Answers

1
votes

It sounds like a task for (inside xsl:template match="p")

    <xsl:for-each-group select="node()" group-adjacent="boolean(self::emph | self::note | self::anchor | self::seg)">
      <xsl:choose>
           <xsl:when test="current-grouping-key()">
              <xsl:copy-of select="current-group()[self::emph], current-group()[self::note], current-group()[self::anchor], current-group()[self::seg]"/>
           </xsl:when>
           <xsl:otherwise>
              <xsl:copy-of select="current-group()"/>
           </xsl:otherwise>
       </xsl:choose>
    </xsl:for-each-group> 

https://xsltfiddle.liberty-development.net/gWvjQgo