PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : XSL: Child nodes kopieren und einige bearbeiten?


Simon
2007-06-26, 08:32:10
Hallo,

ich hab folgenden XML-Block:

<body tg-ref="en-admin" headline="Summary">
Microsoft has issued five new bulletins providing patches to solve
several problems. Due to the criticlality of some of the problems the
application of the patches is <em>highly</em> recommended. <elink target="http://www.microsoft.com">Microsoft</elink>
</body>

Nun will ich den Inhalt der body-Node und aller Child-Nodes (Formatierungen, Links, etc.) kopieren. Das Ergebnis (HTML) sollte so aussehen:
Microsoft has issued five new bulletins providing patches to solve
several problems. Due to the criticlality of some of the problems the
application of the patches is <em>highly</em> recommended. <a href="http:///www.microsoft.com/">Microsoft</a>

Mit dem jetzigen Ansatz iteriere über ich alle Nodes der body-Node und verarbeite die je nach Typ:

<xsl:for-each select="descendant-or-self::*">
<xsl:if test="name() = 'body'">
<b><xsl:value-of select="name()"/></b><xsl:copy-of select="."/>
</xsl:if>
<xsl:if test="name() = 'elink'">
<b>Got a link!</b>
</xsl:if>
</xsl:for-each>


Damit krieg ich zwar die Subnodes verarbeitet, aber halt erst nach dem eigentlichen Inhalt der body-Node. Und der Inhalt der body-Node wird komplett kopiert, inklusive der child-nodes (in dem Fall der Link).

Was kann ich noch versuchen, um das gewünschte Ergebnis zu erreichen? Mehrere Passes machen, wo z.B. der erste Pass die Daten komplett kopiert und der zweite die Links anpasst?

Danke, Enrico

mithrandir
2007-06-26, 12:13:22
Ich bin selbst kein Guru, aber so könnte es klappen (zumindest bei mir):

XML:
<?xml version="1.0" encoding="UTF-8"?>
<documentnode>
<body tg-ref="en-admin" headline="Summary">
Microsoft has issued five new bulletins providing patches to solve
several problems. Due to the criticlality of some of the problems the
application of the patches is <em>highly</em> recommended. <elink target="http://www.microsoft.com">Microsoft</elink>
</body>
<br/>
<body tg-ref="en-admin" headline="Summary">
Microsoft has issued five new bulletins providing patches to solve
several problems. Due to the criticlality of some of the problems the
application of the patches is <em>highly</em> recommended. <elink target="http://www.microsoft.com">Microsoft</elink>
</body>
</documentnode>

XSLT:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt">
<xsl:output method="html" version="3" encoding="iso-8859-1" indent="yes" xalan:omit-meta-tag="yes"/>
<xsl:template match="/">
<HTML>
<head>
<title>Test</title>
</head>
<body>
<xsl:for-each select="documentnode/body">
<p>
<xsl:apply-templates select="*|text()|@*" mode="toc"/>
</p>
</xsl:for-each>
</body>
</HTML>
</xsl:template>
<xsl:template match="documentnode/body/text()|@*" mode="toc">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="documentnode/body/*" mode="toc">
<xsl:choose>
<xsl:when test="name() = 'elink'">
<a style="color:darkblue">
<xsl:attribute name="href">
<xsl:value-of select="@target"/>
</xsl:attribute>
<xsl:value-of select="text()"/>
</a>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

Ausgabe:
<HTML xmlns:xalan="http://xml.apache.org/xslt">
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-16">
<title>Test</title>
</head>
<body>
<p tg-ref="en-admin" headline="Summary">
Microsoft has issued five new bulletins providing patches to solve
several problems. Due to the criticlality of some of the problems the
application of the patches is <em>highly</em> recommended. <a style="color:darkblue" href="http://www.microsoft.com">Microsoft</a></p>
<p tg-ref="en-admin" headline="Summary">
Microsoft has issued five new bulletins providing patches to solve
several problems. Due to the criticlality of some of the problems the
application of the patches is <em>highly</em> recommended. <a style="color:darkblue" href="http://www.microsoft.com">Microsoft</a></p>
</body>
</HTML>

hth, Peter

Simon
2007-06-27, 10:11:21
Wow, vielen Dank =)
Macht jetzt im Nachhinein auch Sinn ;) ;D

Simon
2007-07-02, 09:47:02
Hallo,

ich nochmal ;(

Ich würde gerne folgendes machen in XSL:

for item in list:
applyTemplate(item)


Also ich hab eine Liste (die von außerhalb kommt), da stehen eine Reihe von Namen drin und die Elementen mit diesen Namen sollen bearbeitet werden. Alles, was ich zu Variablen finde, geht nur davon aus, dass ich in einer Variablen einen einzelnen Wert speichern will ;(

Danke, Enrico

mithrandir
2007-07-02, 10:44:51
Wie meinst du das genau, dass du etwas von "außerhalb" bekommst. Ich kenne XSLT nur so, dass eine XML-Basis transformiert wird. Wie ist also deine Liste in XML abgebildet? Oder verstehe ich da etwas falsch?

Variablen oder Schleifen in dem Sinn gibt es in XSL nicht, es ist ja keine Programmiersprache.

Eine gute Anlaufstelle ist übrigens: http://www.w3schools.com/xsl/

Besserwissend
2007-07-02, 11:32:54
Ich würde gerne folgendes machen in XSL:

for item in list:
applyTemplate(item)



Vielleicht hilft Dir das ja weiter:


...

<xsl:template match="erstens">
<xsl:text>erstens</xsl:text>
</xsl:template>

<!-- ... -->

<xsl:template name "foreach_list">
<xsl:param name="liste" select="'erstens,zweitens,drittens,'"/>
<xsl:param name="separator" select="''" />

<!-- applyTemplate(item) -->
<xsl:apply-templates select="substring-before($liste,$separator)" />

<!-- rekursiver Aufruf -->
<xsl:variable name="aktuelleListe" select="substring-after($liste,$separator)" />
<xsl:if test="string-length($aktuelleListe) &gt; 0>
<xsl:call-template name="foreach_list">
<xsl:with-param name="liste" select="$aktuelleListe" />
<xsl:with-param name="separator" select="$separator" />
</xsl:call-template>
</xsl:if>
</xsl:template>

<xsl:template match="/">
<xsl:call-template name="foreach_list">
<xsl:with-param name="liste" select="'hier kommt deine Liste mit dem Trennzeichen _Separator_ rein'" />
<xsl:with-param name="separator" select="' '" />
</xsl:call-template>
</xsl:template>
...

Coda
2007-07-02, 15:08:35
XSLT ist ja auch Turing Complete, kann also theoretisch alles ausrechnen X-D

Simon
2007-08-02, 16:17:59
So, ich nochmal. Ich bin jetzt fast fertig, bis auf eine Sache: Die dt. Umlaute funktionieren nicht :(
Wenn ich Xalan nehme und als Ausgabemodus "html" dann werden Umlaute in den Quelldokumenten richtig umgewandelt. Bei jedem anderen Processor werden Umlaute durch Fragezeichen ersetzt :(
Xalan kann ich nicht verwenden, weil das ganze in einer Web-Anwendung laufen soll. Es gibt zwar Bindings für Python und Xalan, aber die kompilieren nicht mit den Versionen auf dem Server :(

Was kann ich da jetzt machen? Das Encoding 'iso-8859-1' ist sowohl in den Quelldokumenten als auch im XSL-Stylesheet angegeben.
Wenn ich die Umlaute vor der Bearbeitung durch HTML-Dinger ersetze, dann meckert der Processor wegen Entities rum.

Danke, Enrico