Announcement

Collapse
No announcement yet.

Stringvergleich mit contains()

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Stringvergleich mit contains()

    Hallo zusammen,
    ich bin absoluter Neuling hier und auch erst seit ein paar Tagen mit XSLT und XPath befasst. Mein Problem ist folgendes:
    Ich habe eine XML-Datei mit der abgebildeten Struktur eines Vertragstextes.
    Hier ein Ausschnitt:
    Code:
    <paragraf>
                   <no>§ 1</no>
                   <bez>Gegenstand des Vertrages</bez>
                   <absatz>
                      <nr>(1)</nr>
                      <text>Vertragstext Absatz 1
                           <liste>
                                  <zeile>Text einer Aufzähluingsliste</zeile>
                                  <zeile>Text einer Aufzähluingsliste</zeile>
                            </liste>
                        </text>
                    </absatz>
                 </paragraf>
    Mit einer xsl-Datei will ich zunächst den Text als HTML ausgeben und darstellen. Auszug aus der xsl-Datei:
    Code:
    <xsl:template match="paragraf">
    <tr>
    	<td width="670" valign="top">
    	<b><xsl:value-of select="no" /> <xsl:value-of select="bez" /></b>
    	</td>
    </tr>
    <tr>
    	<td width="670" valign="top">
    	<xsl:apply-templates select="absatz"/>
    	</td>
    </tr>
    </xsl:template>
    <xsl:template match="absatz">
    	<table width="670" border="0">
    		<tr>
    			<td width="67" valign="top">
    			<xsl:value-of select="nr" />
    			</td>
    			<td width="603" valign="top">
    			<p>
    			<xsl:apply-templates select="text" />
    			</p>
    			
    			</td>
    		</tr>
    	</table>
    </xsl:template>
    
    <xsl:template match="text">
    <xsl:choose>
    <xsl:when test="contains(current(),string('child::liste/zeile'))">
    <xsl:value-of select="substring-before(current(),string('child::liste/zeile'))" />
    <xsl:apply-templates select="liste" />
    </xsl:when>
    <xsl:otherwise>
    <xsl:value-of select="." />
    </xsl:otherwise>
    </xsl:choose>
    </xsl:template>
    
    <xsl:template match="liste">
    <ul>
    <xsl:for-each select="zeile">
    <li><xsl:value-of select="." /></li>
    </xsl:for-each>
    </ul>
    </xsl:template>
    </xsl:stylesheet>
    Das Problem ist, dass die Liste ein Kindelement von text ist, text aber sowohl einen String als Value haben kann als auch die Liste mit ihren Zeilen.
    Der Templateaufruf "text" aus dem Template "absatz" führt dazu, dass der ganze Inhalt von "text", also ggf. auch die Listenelemente ausgegeben werden, aber nicht als Liste sondern als Fliestext. Ich lasse also mit select="contains(current(),'child::liste/zeile')" prüfen, ob das erste Listenelement im String von "text" enthalten ist. Wenn ja, möchte ich, dass nur der Teilstring vor diesem Element ausgegeben wird. Die Liste erhalte ich durch das Template "liste" in der <ul>-Formatierung.
    Leider liefert contains() in meinem Fall keine korrekten Ergebnisse, denn die HTML-Darstellung zeigt, dass die Listenlemente in dem String von "text" enthalten sind.
    Ich habe die choose-Abfrage auch schon anders gestaltet:
    Code:
    <xsl:when test="child::liste/zeile!=''">
     <xsl:value-of select="substring-before(current(),string('child::liste/zeile'))" />
    <xsl:apply-templates select="liste" />
    </xsl:when>...
    In diesem Fall bekomme ich die Liste aber keinen Text mehr, weil substring-before() einen leeren String zurück liefert.
    Wo ist mein Denkfehler? Wie kann ich dieses Problem anders lösen?
    Für Eure Hilfe wäre ich sehr dankbar.

    Gruß

    Wolfen

  • #2
    Es gibt eingebaute Vorlagen ("built-in templates") http://www.w3.org/TR/xslt#built-in-rule, die in deinem Fall fast alles erledigen, was du willst, also entferne einfach das <xsl:template match="text">...</xsl:template>, das brauchst du nicht, dann klappt es.
    Durch die eingebauten Vorlagen werden dann für "text"-Elemente einfach die Kindsknoten verarbeitet, und so ein Textknoten existiert, wird der ausgegeben, für "liste"-Elemente wird dann die Vorlage verwendet, die du geschrieben hast.

    Comment


    • #3
      Ich hoffe es verstanden zu haben
      Code:
      <?xml version="1.0"?>
      <root>
      	<paragraf>
      		<no>§ 1</no>
      		<bez>Gegenstand des Vertrages</bez>
      		<absatz>
      			<nr>(1)</nr>
      			<text>Vertragstext Absatz 1
      				<liste>
      					<zeile>Text einer Aufzähluingsliste</zeile>
      					<zeile>Text einer Aufzähluingsliste</zeile>
      					<zeile>Text einer Aufzähluingsliste</zeile>
      					<zeile>Text einer Aufzähluingsliste</zeile>
      					<zeile>Text einer Aufzähluingsliste</zeile>
      					<zeile>Text einer Aufzähluingsliste</zeile>
      				</liste>
      			</text>
      		</absatz>
      	</paragraf>
      	<paragraf>
      		<no>§ 2</no>
      		<bez>Gegenstand des Vertrages</bez>
      		<absatz>
      			<nr>(1)</nr>
      			<text>Vertragstext Absatz 1
      				<liste>
      					<zeile>Text einer Aufzähluingsliste</zeile>
      					<zeile>Text einer Aufzähluingsliste</zeile>
      				</liste>
      			</text>
      		</absatz>
      	</paragraf>
      	<paragraf>
      		<no>§ §</no>
      		<bez>Gegenstand des Vertrages</bez>
      		<absatz>
      			<nr>(1)</nr>
      			<text>Vertragstext Absatz 1
      				<liste>
      					<zeile>Text einer Aufzähluingsliste</zeile>
      				</liste>
      			</text>
      		</absatz>
      	</paragraf>
      	<paragraf>
      		<no>§ 4</no>
      		<bez>Gegenstand des Vertrages</bez>
      		<absatz>
      			<nr>(1)</nr>
      			<text>Vertragstext Absatz 1
      				<liste>
      					<zeile></zeile>
      					<zeile>Text einer Aufzähluingsliste</zeile>
      				</liste>
      			</text>
      		</absatz>
      	</paragraf>
      </root>
      Code:
      <?xml version="1.0"?>
      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      	<xsl:output indent="yes" method="html"/>
      	<xsl:template match="/">
      		<xsl:apply-templates select="root"/>
      	</xsl:template>
      
      	<xsl:template match="root">
      		<html>
      			<body>
      				<table border="2px solid">
      					<xsl:apply-templates select="paragraf"/>
      				</table>
      			</body>
      		</html>
      	</xsl:template>
      	<xsl:template match="paragraf">
      		<tr>
      			<td>
      				<xsl:value-of select="concat(no,' - ',bez)"/>
      			</td>
      			<td>
      				<xsl:if test="absatz/text/liste/zeile[1]!=''">
      					<xsl:apply-templates select="absatz"/>
      				</xsl:if>
      			</td>
      		</tr>
      	</xsl:template>
      	<xsl:template match="absatz">
      		<table border="black">
      			<tr>
      				<td>
      					<xsl:value-of select="nr"/>
      				</td>
      				<td>
      
      					<xsl:apply-templates select="text/liste/zeile"/>
      				</td>
      			</tr>
      		</table>
      	</xsl:template>
      	<xsl:template match="zeile">
      
      		<xsl:value-of select="."/>
      		<br/>
      	</xsl:template>
      </xsl:stylesheet>
      ergebnis
      Code:
      <?xml version="1.0"?>
      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      	<xsl:output indent="yes" method="html"/>
      	<xsl:template match="/">
      		<xsl:apply-templates select="root"/>
      	</xsl:template>
      
      	<xsl:template match="root">
      		<html>
      			<body>
      				<table border="2px solid">
      					<xsl:apply-templates select="paragraf"/>
      				</table>
      			</body>
      		</html>
      	</xsl:template>
      	<xsl:template match="paragraf">
      		<tr>
      			<td>
      				<xsl:value-of select="concat(no,' - ',bez)"/>
      			</td>
      			<td>
      				<xsl:if test="absatz/text/liste/zeile[1]!=''">
      					<xsl:apply-templates select="absatz"/>
      				</xsl:if>
      			</td>
      		</tr>
      	</xsl:template>
      	<xsl:template match="absatz">
      		<table border="black">
      			<tr>
      				<td>
      					<xsl:value-of select="nr"/>
      				</td>
      				<td>
      
      					<xsl:apply-templates select="text/liste/zeile"/>
      				</td>
      			</tr>
      		</table>
      	</xsl:template>
      	<xsl:template match="zeile">
      
      		<xsl:value-of select="."/>
      		<br/>
      	</xsl:template>
      </xsl:stylesheet>

      Comment

      Working...
      X