Filtern von Trennstrichen (regular expressions)
Janine
- xml
- xsl
Hallo miteinander,
seit gestern quäle ich mich mit dem Filter für Trennstriche und hoffe, hier auf gute Anregungen oder Tipps zu kommen.
Ich will folgende vier Problemfälle filtern:
Dazu habe ich die einfache Testdatei:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<text>
Klein- buch- stab- en
Funkt- ionale System- risiko- analyse
Projekt- organisa- tions- plan
Groß- Buch- Stab- En
Maschinen- Risiko- analyse
Ferti- gungs- Prüf- vor- schrift
und oder
Prozess- und Komponenten- manage- ment- plan
Reinigungs- oder Hygiene- vorschrift
Gedanken - Strich
Prozess- über- sicht - Stufe 2
Entwickler - Software
</text>
</root>
Für den Fall 1-3 funktioniert das folgende Skript ganz prima:
<xsl:template match="//text">
<root>
<xsl:variable name="fstChange">
<xsl:analyze-string select="." regex="-(
|\s|\n)([A-Z])">
<xsl:matching-substring>-<xsl:value-of select="regex-group(2)"/></xsl:matching-substring>
<xsl:non-matching-substring><xsl:value-of select="."/></xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:variable name="finalChange">
<xsl:analyze-string select="$fstChange" regex="-(
|\s|\n| )(and|und|oder|or )?">
<xsl:matching-substring>
<xsl:choose>
<xsl:when test="regex-group(2) = 'und'">- und</xsl:when>
<xsl:when test="regex-group(2) = 'oder'">- oder</xsl:when>
<xsl:when test="regex-group(2) = 'and'">- and</xsl:when>
<xsl:when test="regex-group(2) = 'or'">- or</xsl:when>
<xsl:otherwise></xsl:otherwise>
</xsl:choose>
</xsl:matching-substring>
<xsl:non-matching-substring><xsl:value-of select="."/></xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:value-of select="$finalChange"/>
</root>
</xsl:template>
Und für die Gedankenstriche klappt das hier:
<xsl:template match="//text">
<root>
<xsl:variable name="finalChange">
<xsl:analyze-string select="." regex="(
|\s|\n)-(
|\s|\n)">
<xsl:matching-substring><xsl:value-of select="regex-group(1)"/>-<xsl:value-of select="regex-group(2)"/></xsl:matching-substring>
<xsl:non-matching-substring><xsl:value-of select="."/></xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:value-of select="$finalChange"/>
</root>
</xsl:template>
Mein Problem ist nun, beides zusammenzupacken. Wenn ich alles in ein Template schreibe (mit der Variablen "secChange"), wird meine Gedankenstrich-Variable dennoch übergangen. Habt ihr eine Ahnung, warum? Oder gibt es eine elegantere Möglichkeit?
Bin für jeden Hinweis dankbar! Liebe Grüße, Janine
@@Janine
- Gedanken - Strich -> Gedanken - Strich (so belassen)
So belassen? Merke: Der Bindestrich steht nie zwischen zwei Leerzeichen! ➳ Binde- und Gedankenstrich
LLAP 🖖
Es geht hierbei um den Gedankenstrich, nicht um den Bindestrich ;)
Wie im Beispiel: "Prozessübersicht - Stufe 2" oder wie in der Formatierungsvorlage meines Unternehmens: "Entwickler - Software"
@@Janine
Es geht hierbei um den Gedankenstrich, nicht um den Bindestrich ;)
Wie im Beispiel: "Prozessübersicht - Stufe 2" oder wie in der Formatierungsvorlage meines Unternehmens: "Entwickler - Software"
Eben. Der Bindestrich '-' ist kein Gedankenstrich; der Halbgeviertstrich '–' ist einer.
Wie in „Prozessübersicht – Stufe 2“ oder „Entwickler – Software“.
LLAP 🖖
Es ist mir egal, wie der Strich heißt oder wie lang er ist. Es geht mir bei dem Problem lediglich um den XSL-Code und dass ich in den angegebenen Beispielen zum einen Strich und Leerzeichen filtern und zum anderen Leerzeichen, Strich und Leerzeichen beibehalten will.
Eine typografische Diskussion sollte an dieser Stelle nicht im Vordergrund stehen.
Besten Dank.
Hallo,
Eine typografische Diskussion sollte an dieser Stelle nicht im Vordergrund stehen.
Wäre aber zielführend.
Gruß
Kalk
Eine typografische Diskussion sollte an dieser Stelle nicht im Vordergrund stehen.
Wäre aber zielführend.
Gruß
Kalk
Inwiefern? Würde das etwas am Template ändern? Ich kann euch durch diese kurzen Kommentare nicht folgen.
Hallo,
Inwiefern?
Es handelt sich um tatsächlich unterschiedliche Zeichen, nicht um unterschiedliche Bezeichnungen desselben Zeichens. Das sollte dein Script berücksichtigen und einsetzen.
Gruß
Kalk
Es handelt sich um tatsächlich unterschiedliche Zeichen, nicht um unterschiedliche Bezeichnungen desselben Zeichens. Das sollte dein Script berücksichtigen und einsetzen.
Die Quelldatei wird bei uns aus einer bestimmten Software generiert und besitzt eine sehr fixe Struktur und nur eingeschränkte Zeichen. Aus diesen muss ich versuchen, das Maximum rauszuholen und schicke HTML-Seiten zu basteln. Also kann ich leider nicht einfach sagen, dass es einen Unterschied zwischen Binde- und Gedankenstrich in der Quell-XML gibt, da er syntaktisch nicht vorhanden ist.
Daher erneut meine Frage vom ersten Posting: Wie kann man mit den regex die verschiedenen Fälle filtern, um die Ausgabe dementsprechend anzupassen. Ob die Ausgabe später einen Binde- oder Gedankenstrich (–) enthält, ist leicht umzusetzen. Mein Problem ist eher die vorhergehende Analyse.
Hallo Janine,
Mein Problem ist nun, beides zusammenzupacken. Wenn ich alles in ein Template schreibe (mit der Variablen "secChange"), wird meine Gedankenstrich-Variable dennoch übergangen. Habt ihr eine Ahnung, warum? Oder gibt es eine elegantere Möglichkeit?
Probiere es so (ohne Garantie auf Abdeckung aller – außer den genannten – möglichen Fälle):
<xsl:template match="//text">
<root>
<xsl:variable name="fstChange">
<xsl:analyze-string select="." regex="-(\s|\n)([A-Z])">
<!-- 
| -->
<xsl:matching-substring>-<xsl:value-of select="regex-group(2)"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:variable name="secChange">
<xsl:analyze-string select="$fstChange" regex="-(\s|\n|\s)(and|und|oder|or )?">
<xsl:matching-substring>
<xsl:choose>
<xsl:when test="regex-group(2) = 'und'">- und</xsl:when>
<xsl:when test="regex-group(2) = 'oder'">- oder</xsl:when>
<xsl:when test="regex-group(2) = 'and'">- and</xsl:when>
<xsl:when test="regex-group(2) = 'or'">- or</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:variable name="finalChange">
<xsl:analyze-string select="$secChange" regex="(\s|\n)-">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"/>- <xsl:value-of select="regex-group(2)"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:value-of select="$finalChange"/>
</root>
</xsl:template>
Grüße, Thomas
Hallo Thomas,
besten Dank für dein Template, es funktioniert für die Testfälle super! Jetzt muss ich nur noch verstehen, was du da gemacht hast ;)
Die Variable finalChange kann man auch so definieren:
<xsl:variable name="finalChange">
<xsl:analyze-string select="$secChange" regex="(\s|\n)-">
<xsl:matching-substring> - </xsl:matching-substring>
<xsl:non-matching-substring><xsl:value-of select="."/></xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:variable>
Viele Grüße, Janine