Attribute ersetzen
Steffen J
- xsl
0 Thomas J.S.0 Steffen J0 Steffen J0 Steffen J
Hallo ich habe folgendes Problem.
Ich möchte eine vorhandene XML durchlaufen und alle Attribute vergleichen und falls möglich ersetzten.
Das ganze soll eine Übersetzung der Attribute in eine andere Sprache darstellen.
Das Wörterbuch hat folgenden Aufbau
<tmx>
<body>
<tu>
<tuv xml:lang="en">
<seg>example</seg>
</tuv>
<tuv xml:lang="de">
<seg>Beispiel</seg>
</tuv>
</tu>
<tu>
<tuv xml:lang="en">
<seg>hi</seg>
</tuv>
<tuv xml:lang="de">
<seg>Hallo</seg>
</tuv>
</tu>
</body>
</tmx>
Die zu Übersetzende Quell-Datei
<Test>
<ABC Attribute1="Beispiel" Attribute2="Hallo"/>
</Test>
auch die Erweiterung auf weitere sprachen sollte unterstützt werden.
Bin für jede Hilfe dankbar.
Hallo,
Hallo ich habe folgendes Problem.
Ich möchte eine vorhandene XML durchlaufen und alle Attribute vergleichen und falls möglich ersetzten.
Das ganze soll eine Übersetzung der Attribute in eine andere Sprache darstellen.
auch die Erweiterung auf weitere sprachen sollte unterstützt werden.
Bin für jede Hilfe dankbar.
Wie lauten deine Fragen?
Grüße
Thomas
Hi und zwar weis ich nicht wie ich die einzelnen Attribute nacheinander ansprechen kann.Um sie dann zu vergleichen.
also das ist mein ansatz.
<xsl:variable name="target_lang" select="en"/>
<xsl:variable name="source_lang" select="de"/>
<xsl:variable name="dict" select="document('ProgalDict.tmx')"/>
<xsl:template match="@*">
<xsl:variable name="thisWord" select="normalize-space(.)" />
<xsl:variable name="dictWord_de" select="$dict/tmx/body/tu/tuv[@xml:lang=$source_lang]/seg" />
<xsl:variable name="dictWord_en" select="$dictWord_de/../../tuv[@xml:lang=$target_lang]/seg" />
xsl:choose
<xsl:when test="$dictWord_de[.]=$thisWord">
<xsl:value-of select="$dictWord_en[.]" />
</xsl:when>
xsl:otherwise
<xsl:value-of select="$thisWord" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
So jetzt hab ichs hinbekommen bis auf ne kleinigkeit.
das stylesheet vergleicht und ersetzt jetzt alle attribute die im wörterbuch übersetzt sind.
so nun zur kleinigkeit: ich brauche entweder einen weg wie ich die for schleife nach dem finden des entsprechenden wortes verlassen kann. soweit ich aber geleesn habe ist das mit der for schleife nicht so ganz einfach das diese anderst funktioniert wie in java oder ++.oder eine vernünftige anweisung was er tun soll wenn er es gefunden hat. normal würde ich das einfach mit nem boolean machen aber mit variablen siehts ja ähnlich aus wie mit der for schleife.
hat jemand ne idee wie ich aus der for schleife rauskomm oder die bedingung so umschreiben kann das nur ein wort ausgegeben wir.
hier noch der code.
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="target_lang" select="en"/>
<xsl:template match="/">
<xsl:apply-templates select="node()" mode="translate">
<xsl:with-param name="target_lang">en</xsl:with-param>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="node()" mode="translate">
<xsl:param name="target_lang"/>
xsl:copy
<xsl:apply-templates select="node()|@*" mode="translate">
<xsl:with-param name="target_lang" select="$target_lang"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@*" mode="translate">
<xsl:param name="target_lang"/>
<xsl:attribute name="{name()}">
<xsl:call-template name="trans">
<xsl:with-param name="target_lang" select="$target_lang"/>
<xsl:with-param name="thisWord" select="."/>
</xsl:call-template>
</xsl:attribute>
</xsl:template>
<xsl:template name="trans">
<xsl:param name="target_lang"/>
<xsl:param name="thisWord"/>
<xsl:variable name="dict" select="document('ProgalDict.tmx')"/>
<xsl:variable name="source_lang" select="$dict/tmx/header/@srclang"/>
<!-- so hier is das problem-->
<xsl:for-each select="$dict/tmx/body/*">
xsl:choose
<xsl:when test="tuv[@xml:lang=$source_lang]/seg=$thisWord">
<xsl:value-of select="tuv[@xml:lang=$target_lang]/seg" />
</xsl:when>
xsl:otherwise
<xsl:if test="$dict/tmx/body/tu[last()]/tuv[last()]=tuv[last()]">
<xsl:value-of select="$thisWord" />
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Hallo,
So jetzt hab ichs hinbekommen bis auf ne kleinigkeit.
Das saprt Zeit (für mich) ;-)
so nun zur kleinigkeit: ich brauche entweder einen weg wie ich die for schleife nach dem finden des entsprechenden wortes verlassen kann. soweit ich aber geleesn habe ist das mit der for schleife [...]
for-each ist keine Schleife.
Betrachte for-each einfach als eine andere Art vom Template. Es wird für jeden der Knoten auf dem die Bedingung (im select="") passt, neu instantiiert.
<!-- so hier is das problem-->
<xsl:for-each select="$dict/tmx/body/*">
xsl:choose
<xsl:when test="tuv[@xml:lang=$source_lang]/seg=$thisWord">
<xsl:value-of select="tuv[@xml:lang=$target_lang]/seg" />
</xsl:when>
xsl:otherwise
<xsl:if test="$dict/tmx/body/tu[last()]/tuv[last()]=tuv[last()]">
<xsl:value-of select="$thisWord" />
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
Na ja du machst die Ausgabe aber auch für jedes Element im body.
Was du hier suchts ist eigentlich:
<xsl:for-each select="$dict/tmx/body/tu[tuv[@xml:lang=$source_lang]/seg = $thisWord]">
Was du mit "if" im "otherwise" testen willst bzw. der Sinn dahinter, ist mir aber nicht klar.
An deiner Stelle würde ich aber auf das for-ech im Attribut-Template verzeichten und dies weiter oben machen:
--------------------------------------------
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="targetLang"/>
<xsl:variable name="dict" select="document('ProgalDict.tmx')"/>
<xsl:variable name="source_lang" select="$dict/tmx/header/@srclang"/>
<xsl:template match="/">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*">
xsl:copy
<xsl:for-each select="@*">
<xsl:attribute name="{name()}">
<xsl:call-template name="trans">
<xsl:with-param name="target_lang" select="$targetLang"/>
<xsl:with-param name="thisWord" select="."/>
</xsl:call-template>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="*"/>
</xsl:copy>
</xsl:template>
<xsl:template name="trans">
<xsl:param name="target_lang"/>
<xsl:param name="thisWord"/>
xsl:choose
<xsl:when test="$dict/tmx/body//tuv[@xml:lang=$source_lang]/seg=$thisWord">
<xsl:value-of select="$dict/tmx/body/tu[tuv[@xml:lang=$source_lang]/seg=$thisWord]/tuv[@xml:lang=$target_lang]/seg"/>
</xsl:when>
xsl:otherwise
<xsl:if test="$dict/tmx/body/tu[last()]/tuv[last()]=tuv[last()]">
<xsl:value-of select="$thisWord"/>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
------------------------------------------------
Grüße
Thomas
Hi danke für die hilfe funktioniert einwandfrei.
Hab noch die target_lang angepasst. als variable muss man die dann nicht so oft durchreichen. die if-anweisung hatte ich wegen der for-each. da ich so oft durchgelaufen bin wie übersetzungen für das deutsche wort vorhanden waren und so das deutsche wort beim vergleich zu oft ausgegeben habe. darum der vergleich ob ich am ende des knotens bin.
so hier noch der fertige code. danke noch mal.
gruss steffen
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="target_lang" select="'en'"/>
<xsl:variable name="dict" select="document('ProgalDict.tmx')"/>
<xsl:variable name="source_lang" select="$dict/tmx/header/@srclang"/>
<xsl:template match="/">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*">
xsl:copy
<xsl:for-each select="@*">
<xsl:attribute name="{name()}">
<xsl:call-template name="trans">
<xsl:with-param name="thisWord" select="."/>
</xsl:call-template>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="*"/>
</xsl:copy>
</xsl:template>
<xsl:template name="trans">
<xsl:param name="thisWord"/>
xsl:choose
<xsl:when test="$dict/tmx/body/tu/tuv[@xml:lang=$source_lang]/seg=$thisWord">
<xsl:value-of select="$dict/tmx/body/tu[tuv[@xml:lang=$source_lang]/seg=$thisWord]/tuv[@xml:lang= $target_lang]/seg"/>
</xsl:when>
xsl:otherwise
<xsl:value-of select="$thisWord"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>