Janine S.: Template Match über mehrere Tags

Hallo allerseits,

ich habe bereits einige XSL-Erfahrung, komme hierbei allerdings an meine Grenzen des Vorstellungsvermögens und hoffe, dass ihr meinen Kopfknoten lösen könnt 😉

Ich habe im Word-ML folgende (ideale) XML-Quellstruktur:

<w:p>
	<w:r>Geltungsbereich:</w:r>
	<w:r>[validity]</w:r>
</w:p>

Über meine XSL will ich den <w:r>[validity]</w:r> im gesamten Dokument finden und den Inhalt [validity] durch einen Wert aus einer Variablen ersetzen. Das funktionierte bisher immer gut mit <xsl:template match="//w:r[.='[validity]']"> und die weiteren Schritte innerhalb des Templates.

Da Word allerdings doof ist und der XML-Code beim Öffnen mit Microsoft immer wieder zerschossen wird, kann ich u.a. auch folgende Quellstrukturen haben:

<w:p>
	<w:r>Geltungsbereich:</w:r>
	<w:r>[</w:r>
	<w:r>validity]</w:r>
</w:p>

oder

<w:p>
	<w:r>Geltungsbereich:</w:r>
	<w:r>[</w:r>
	<w:r>validity</w:r>
	<w:r>]</w:r>
</w:p>

Mein <xsl:template match="//w:r[.='[validity]']"> funktioniert an dieser Stelle also nicht mehr. Ich könnte auch nach <xsl:template match="//w:r[.='validity']"> (ohne eckige Klammern) suchen, doch dann habe ich den 2. Fall nicht abgebildet und bekomme die überflüssigen Klammern in den andern <w:r> nicht gleich mit herausgefiltert...

Vielleicht könnte man auch nach <xsl:template match="//w:p[contains(.//w:r,'Geltungsbereich:')]"> suchen und das gesamte w:p ersetzen, erscheint mir aber etwas umständlich. Gibt es dafür nicht eine smartere Lösung?

Ich freue mich auf eure Antworten 😀

Grüße Janine

akzeptierte Antworten

  1. Hallo Janine,

    Vielleicht könnte man auch nach <xsl:template match="//w:p[contains(.//w:r,'Geltungsbereich:')]"> suchen und das gesamte w:p ersetzen, erscheint mir aber etwas umständlich. Gibt es dafür nicht eine smartere Lösung?

    Ist etwas schwierig zu interpretieren, ohne die Codebasis drumherum zu kennen. Mal ein Denkansatz:

    <xsl:template match="//w:p[w:r[1][contains(., 'Geltungsbereich:')]]">
    
      <xsl:variable name="check">
        <xsl:copy-of select="w:r[position() > 1]/text()"/>
        <!-- hier entsteht in allen genannten Fällen [validity] -->
      </xsl:variable>
    
      <xsl:if test="$check = '[validity]'">
        <w:p>mach was …</w:p>
      </xsl:if>
    
    </xsl:template>
    
    

    Falls im w:p weitere als die genannten w:r folgen, passt der zusammenkopierte Vergleich schon nicht mehr. Dann sind weitere einschränkende Abfragen nötig.

    Grüße,
    Thomas

    1. Hallo Thomas,

      vielen Dank für deinen Denkansatz. Ich habe das Problem nun ein wenig anders gelöst, da ich noch sehr viel Code drumherum habe und nicht so einfach mit xsl:copy-of arbeiten konnte.

      Ich filtere zunächst nach "Geltungsbereich" im ersten w:r (was bisher von Word noch nie zerschossen wurde), schreibe dann w:p komplett neu und füge, je nach Inhalt des w:r (es gibt noch mehr) meine Variablen ein. Sehr komplex, aber leider dank WordML nicht anders lösbar...

      <xsl:template match="//w:p[contains(.//w:r,'Geltungsbereich') or contains(.//w:r,'Scope') or contains(.//w:r,'Vertraulichkeitsklasse') or contains(.//w:r,'Confidentiality Class')]">
         <xsl:variable name="descr" select=".//w:r"/>
         <w:p>
            <!--Hier stehen weitere xsl:attribute und Word-Formatierungstags-->
            <w:r>
               <!--Hier kommen nochmal viele xsl:attribute und Word-Formatierungstags-->
               <xsl:choose>
                  <xsl:when test="contains($descr,'Geltungsbereich') or contains($descr,'Scope')">
                     <xsl:value-of select="$istrings/text[@name='scope']/* [local-name () = $lang]"/>
                  </xsl:when>
                  <xsl:when test="contains($descr,'Vertraulichkeitsklasse') or contains($descr,'Confidentiality Class')">
                     <xsl:value-of select="$istrings/text[@name='confidentiality']/* [local-name () = $lang]"/>
                  </xsl:when>
                  <xsl:otherwise>
                     <xsl:text>FEHLER</xsl:text>
                  </xsl:otherwise>
               </xsl:choose>
            </w:r>
         </w:p>
      </xsl:template>
      

      Trotzdem danke für deinen Denkanstoß 😉 Viele Grüße Janine