xml->xsl->html

DC-7C

Mitglied
Hallo Allerseits!

bin beim konvertieren vom XML nach HTML mittels XSLT auf folgendes Problem gestoßen. Es gibt ein Tag namens title, daß noch ein Tag enthält:

<title><subtitle>2.1</subtitle>Anleitung</title>

Nun zum Problem: zwischen "subtitle" und den Rest muß ein Leerzeichen platziert werden, es soll in HTML also so aussehen:
<title>2.1 Anleitung</title>

Habe schon viele Varianten ausprobiert, bin wirklich ratlos. Kann mir jemand einen Tipp geben, wie ich es am besten lösen könnte

Vielen dank im voraus!
 
Wie wäre es, wenn du an geeigneter Stelle ein &nbsp; einfügst (non-breaking space)?
vop
 
Hi!

noch eine Frage.

Ich habe in der XML-Datei folgendes:
Code:
<para>
  <bold>text</bold>
  <italic>test</italic>
  Eigentliche Text
  <bold>test</bold>
</para>
Ich weiß, ziemlich blöd, leider habe ich keinen Einfluß auf die XML-Struktur. Anzahl der Tags, die vor eigentlichem Text steht, kann sich ändern. Wie kann ich <xsl:apply templates> nur für die Tags aufrufen, die vor dem eigentlichen Text stehen? Und wie kann ich auf den Rest zugreifen? (Text und restliche Tags).

Vielen Dank im voraus!
 
zum Testen
Code:
<?xml version="1.0"?>
<root>
	<para>
		<bold>textbold</bold>
		<italic>testitalic</italic>Eigentliche Text
		<bold>testbold</bold>
	</para>
	<para>
		<bold>textbold</bold>
		<italic>testitalic</italic>Eigentliche Text
		<bold>testbold</bold>
	</para>
</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>
			<xsl:apply-templates select="para"/>
		</html>
	</xsl:template>
	<xsl:template match="para">
		<p>
			<xsl:apply-templates/>
		</p>
	</xsl:template>
	<xsl:template match="text()">
		<xsl:value-of select="."/>
	</xsl:template>
	<xsl:template match="bold">
		<b>
			<xsl:value-of select="."/>
		</b>
	</xsl:template>

	<xsl:template match="italic">
		<i>
			<xsl:value-of select="."/>
		</i>
	</xsl:template>
</xsl:stylesheet>

Ergebnis

Code:
<html>
  <p>
		
    <b>textbold</b>
		
    <i>testitalic</i>Eigentliche Text
		
    <b>testbold</b>
	
  </p>
  <p>
		
    <b>textbold</b>
		
    <i>testitalic</i>Eigentliche Text
		
    <b>testbold</b>
	
  </p>
</html>
 
Danke! Sorry, aber das ist nicht das, was ich brauche. Tut mir Leid, die Frage war ziemlich chaotisch formuliert.

Was ich als Ergebnis brauche, ist das die Kind-Elemente, die vor dem Text stehen, und deren Anzahl sich variieren kann, in der HTML-Datei in ein "sonder-div" gepackt sind, der Rest - in ein anderes.

Ungefähr so:

Code:
<html>
<body>
  <div class="div1">
    <b>bold</b>
    <i>testitalic</i>
  </div>
  <div class="div2>
    Eigentliche Text <b>mit</b> möglichen <i>weiteren</i> Tags
  </div>
</body>
</html>

Ich habe es eigentlich fast gelöst. Aber ein wenig geschummelt dabei. Ein Tag, sagen wir, es heißt <const> ist immer dabei und steht immer vor dem Text. Ich habe also dessen Position ermittelt und alles, was vor dieser Position sich befindet, in 1. div gepackt, den Rest in 2.div. Also, erstmal läuft alles, wie gewünscht. Nur aus reiner Neugier - was für die Möglichkeiten hätte ich denn, wenn dieser "const"-Tag nicht da wäre?

Hier ist mein Template:

Code:
<xsl:template match="//para">
  <xsl:variable name="pos" select="(count(*[name()='const']/preceding-sibling::*) + 1)"/>
 <div class="div1">
  	<xsl:apply-templates select="*[(position()&lt;$pos)]"/>
 </div>
 <div class="div2">
 	<xsl:apply-templates select="text()|*[(position()&gt;$pos)]"/>
 </div>
 </div>
</xsl:template>
<xsl:template match="bold">
  <b>
      <xsl:value-of select="."/>
  </b>
</xsl:template>

<xsl:template match="italic">
  <i>
	<xsl:value-of select="."/>
  </i>
</xsl:template>
 
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="html"/>
	</xsl:template>

	<xsl:template match="html">
		<html>
			<xsl:apply-templates select="body/div"/>
		</html>
	</xsl:template>
	<xsl:template match="div">
		<xsl:element name="div">
			<xsl:attribute name="class">
				<xsl:value-of select="@class"/>
			</xsl:attribute>
			<xsl:apply-templates/>
		</xsl:element>
	</xsl:template>
	<xsl:template match="b">
		<b>
			<xsl:value-of select="."/>
		</b>
	</xsl:template>
	<xsl:template match="i">
		<i>
			<xsl:value-of select="."/>
		</i>
	</xsl:template>
	<xsl:template match="text()">
		<xsl:value-of select="."/>
	</xsl:template>
</xsl:stylesheet>
 
hm... sorry, aber ich glaube, wir haben aneinander vorbei geredet.
Ich habe gepostet das, was ich als Ergebnis brauche - also, HTML. Und der zweite Codeschnipsel war XSLT-Template.
 
Code:
<?xml version="1.0"?>
<root>
	<para>
		<bold>text</bold>
		<italic>test</italic>Eigentliche Text
		<bold>test</bold>
	</para>
	<para>
		<bold>text</bold>
		<italic>test</italic>Eigentliche Text
		<bold>test</bold>
	</para>
</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>
			<xsl:apply-templates select="para"/>
		</html>
	</xsl:template>
	<xsl:template match="para">
		<xsl:element name="div">
			<xsl:attribute name="class">
				<xsl:value-of select="concat('div',position())"/>
			</xsl:attribute>
			<xsl:apply-templates/>
		</xsl:element>
	</xsl:template>
	<xsl:template match="bold">
		<b>
			<xsl:value-of select="."/>
		</b>
	</xsl:template>
	<xsl:template match="italic">
		<i>
			<xsl:value-of select="."/>
		</i>
	</xsl:template>
	<xsl:template match="text()">
		<xsl:value-of select="."/>
	</xsl:template>
</xsl:stylesheet>

Code:
<html>
  <div class="div1">
		
    <b>text</b>
		
    <i>test</i>Eigentliche Text
		
    <b>test</b>
	
  </div>
  <div class="div2">
		
    <b>text</b>
		
    <i>test</i>Eigentliche Text
		
    <b>test</b>
	
  </div>
</html>
 
Ich danke Dir für Deine Mühe, aber... Es ging mir um zerteilen des Inhalts: Alles, was vor dem Text (also, vor dem Ergebnis von text()) kommt, in <div1> packen und den Rest (Text und die restliche Tags) in <div2> (und nicht alles mal in div1 und danach in div2).
Wie schon erwähnt, konnte ich das Problem lösen. Die Frage die ich immer noch habe: wie könnte ich die Position des letzten Tags vor text() ermitteln, wenn ich kein bestimmtes Tag hätte, das immer da steht? oder die Position vom Text selbst vielleicht? Habe schon viel gesucht, konnte aber keine vernünftige Antwort finden.
 
Zurück