ThomasM: XSL | Satz in einzelne Wörter zerlegen

Beitrag lesen

Hallo Janine,

Ziel sollte etwas in dieser Art sein:

<?xml version="1.0" encoding="UTF-8"?>
<all>
	<def actterm="Abhilfemaßnahme (FDA)" actdescr="Routine-Instandhaltung oder Wartung eines Gerätes etc.">
		<descr>&lt;a&gt;Routine&lt;/a&gt;-Instandhaltung oder Wartung eines &lt;a&gt;Gerät&lt;/a&gt;es etc.</descr>
	</def>
	<def actterm="Routine" actdescr="Hier taucht der Begriff Abhilfemaßnahme (FDA) auf.">
		<descr>Hier taucht der Begriff &lt;a&gt;Abhilfemaßnahme (FDA)&lt;/a&gt; auf.</descr>
	</def>
	<def actterm="Gerät" actdescr="Dies ist ein Test für Routine und Abhilfemaßnahme (FDA).">
		<descr>Dies ist ein Test für &lt;a&gt;Routine&lt;/a&gt; und &lt;a&gt;Abhilfemaßnahme (FDA)&lt;/a&gt;.</descr>
	</def>
</all>

Das habe ich unter Rückgriff auf zwei Funktionen von FunctX erreicht [functx:replace-multi und functx:if-absent]. Ist schon eine ziemlich wilde Konstruktion geworden, vor allem um den Part mit (FDA) richtig einzubeziehen, dafür die replace-Aktionen. Die runden Klammern sind ja selbst Teile von regulären Ausdrücken zur Gruppierung.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:fn="http://www.w3.org/2005/xpath-functions"
  xmlns:functx="http://www.functx.com"
  exclude-result-prefixes="#all">

  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

  <xsl:function name="functx:replace-multi" as="xs:string?">
    <xsl:param name="arg" as="xs:string?"/>
    <xsl:param name="changeFrom" as="xs:string*"/>
    <xsl:param name="changeTo" as="xs:string*"/>

    <xsl:sequence select="if(fn:count($changeFrom) > 0) then
      functx:replace-multi(replace($arg, $changeFrom[1],
      functx:if-absent($changeTo[1], '')), $changeFrom[fn:position() > 1],
      $changeTo[fn:position() > 1]) else $arg"/>
  </xsl:function>

  <xsl:function name="functx:if-absent" as="item()*">
    <xsl:param name="arg" as="item()*"/>
    <xsl:param name="value" as="item()*"/>

    <xsl:sequence select="if(fn:exists($arg)) then $arg else $value"/>
  </xsl:function>

  <xsl:template match="definitions">
    <xsl:variable name="from" select="for $s in //def/term return
      fn:replace(fn:replace($s, ' \(', '_'), '\)', '~')" as="xs:string*"/>

    <xsl:variable name="to" select="for $s in $from return
      fn:concat('&lt;a&gt;', fn:replace(fn:replace($s, ' \(', '_'), '\)', '~'),
      '&lt;/a&gt;')" as="xs:string*"/>

    <all>
      <xsl:for-each select="def">
        <def actterm="{term}" actdescr="{descr}">
          <descr>
            <xsl:value-of select="fn:replace(fn:replace(
              functx:replace-multi(fn:replace(fn:replace(descr, ' \(', '_'), '\)', '~'),
              $from, $to), '_', ' ('), '~', ')')"/>
          </descr>
        </def>
      </xsl:for-each>
    </all>
  </xsl:template>

</xsl:stylesheet>

Viel Spaß damit. 😉

Grüße,
Thomas