# XSLT: sowohl value-of select "element" als auch "element" selbst ausgeben



## RalU (16. Januar 2010)

Hallo,
ich bin Neuling in Sachen XSLT und möchte folgendes XML-Document für die Ausgabe in HTML mit XSLT bearbeiten:

XML-Document:

```
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Using the xslt-stylesheet -->
<?xml-stylesheet type="text/xsl" href="thesisstyle.xsl"?>
<thesis>
   <abstract-in-german>Test-Thesis</abstract-in-german>
   <abstract-in-english>This is a test-thesis about XML</abstract-in-english>
   <introduction>
      <motivation>Viel Motivation</motivation>
      <aims-of-the-work>XML soll funktionieren!</aims-of-the-work>
   </introduction>
    <related-work>
      <work>Testarbeit1</work>
      <work>Testarbeit2</work>
      <work>Testarbeit3</work>
   </related-work>
   <foundation>Webtech-Vorlesung</foundation>
   <concept>Grundlagen in XML, DTD verstehen</concept>
   <realization>1. DTD bilden, 2.XML-Dokument schreiben</realization>
   <implementation>implementiert mit einem beliebigen Editor</implementation>
   <example>Dies ist ein Beispiel</example>
   <scenario>Dies ist das 1. Szenario</scenario>
   <scenario>Dies ist ein weiteres Szenario</scenario>
   <resume-and-outlook>XML und DTD sind zukunfstweisend!</resume-and-outlook>
   <literature>
     <entry title="XML leicht &amp; verstÄndlich"
         author="Hanke"
         publisher="KnowWare-Verlag"
         year="2003">KnowWare-Heft - Thema XML
      </entry>
   </literature>
</thesis>
```
Die formatierte Ausgabe mit Hilfe des xslt-Stylesheets erfordert nun unter anderem folgende Punkte:
Sämtliche Element unter <thesis> sollen als html-überschrift <h1> ausgegeben werden. Die einzelnen Inhalte,
die ich ja dann mit xslt: value-of select "element" erhalte sollen als Paragraph <p> ausgegeben werden.
Also z.B. 
<h1>abstract-in-german</h1><p>Test-Thesis</p>
<h1>abstract-in-english</h1><p>This is a test-thesis about XML</p>
usw....

Jetzt hab ich zur Lösung folgendes XSLT-Stylesheet versucht:

```
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <head>
            <title>Thesis</title>
            </head>
            <body>
                <xsl:apply-templates />
            </body>
        </html>
    </xsl:template>
    
    <xsl:template match="."> <!-- für jeden Unterpunkt soll folgende Formatierung gelten ... -->
        <h1>"."</h1>             <!-- Ist es möglich, das jeweilige xml-tag auszugeben, ohne es expliziet anzusprechen? -->
        <p><xsl:value-of select="."/></p> <!-- Entsprechend soll hier der Wert des jeweiligen xml-Tags ausgegeben werden und zwar als Paragraph. -->
    </xsl:template>
    
</xsl:stylesheet>
```
Meine Frage erschließt sich eigentlich schon aus den Kommentaren im XSLT-Code oben. Gibt es also eine Möglichkeit, ähnlich wie mit <xsl:value-of select="."> nicht nur den WERT der jeweiligen Knoten auszugeben, sondern auch die Knoten selbst?


----------



## Sven Mintel (16. Januar 2010)

Moin,

klingt, als suchtest du *xsl:copy*


----------



## RalU (16. Januar 2010)

hm, ich weiß nicht so recht, ob das mit xsl:copy geht.

Ich geb hier einfach mal die resultierende html-Ausgabe an, dass durch die xslt-Transformation später herauskommen soll.


```
<html>
 <head>
   <title>Thesis</title>
   </head>
   <body>
     <h1>abstract-in-german</h1>
     <p>content dieses knotens</p>
     <h1>abstract-in-english</h1>
     <p>content dieses knotens</p>
    <h1>introduction</h1>
    <p>
       <h2>motivation</h2>
        <p>content des motivation-Knoten</p>
       <h2>aims-of-the-work</h2>
       <p>content des aims-of-the-work-Knoten</p>
    </p>
     <h1>related-work</h1>
      <p> 
           <h2>work</h2>
           <p>content des ersten work-Knoten</p>
           <h2>work</h2>
           <p>content des nächsten work-Knoten</p>
           <!--beliebig oft wiederholen-->
     </p>
    <h1>foundation</h1>
    <p>content des foundation-Knotens</p>
   <!--- usw. mit allen anderen Knoten -->
   <h1>literature</h1>
   <p>
     <h3>title</h3>
     <p>autor</p>
     <p>content des autor-Knotens</p>
     <p>publisher</p>
     <p>content des publisher-Knotens</p>
     <p>year</p>
     <p>content des year-Knotens</p>
     <h3>title</h3> <!-- beliebig oft wiederholen, wenn noch andere titel unter literature auftauchen...-->
    </p>
</body>
</html>
```
Wie kann ich jetzt in meiner xsl-Datei auf die einzelnen entries zugreifen, ohne dass ich diese expliziet
mit Namen ansprechen muss?
Also nicht z.b. 

```
<xsl:template match="abstract-in-german">
            <h1>abstract-in-german</h1>
        <p><xsl:value-of select="."/></p>
    </xsl:template>

dann als nächstes
<xsl:template match="abstract-in-english">
            <h1>abstract-in-english</h1>
        <p><xsl:value-of select="."/></p>
    </xsl:template>
und so weiter, bis ich alle Knoten durch hab....
```
Ich möchte stattdessen sowas in der Art wie:

```
<xsl:template match="/">
         <h1>Name des jeweiligen Knotens</h1> <!-- Wie kann man den Namen ansprechen? geht dies mit xsl-copy? -->
         <p><xsl:value-of select="."/></p>
     </xsl:template>
```
anwenden und zwar nur einmal aufschreiben, so dass es für alle Knoten gilt....
ggf. käme auch for-each in Betracht. Wie ist sowas zu bewerkstelligen?


----------



## Sven Mintel (17. Januar 2010)

Achso,

dafür gibts die XPath-Function name()


```
<xsl:value-of select="name()" />
```


----------



## RalU (17. Januar 2010)

Ok, vielen Dank für den Hinweis. Damit ist zumindest ein Problem mal behoben!

Jetzt frage ich mich, ob es irgenwie möglich ist, für ALLE  Knoten ein Template auszufüren, dass bspw. ein bestimmtes HTML-Output erzeugt, ohne dass ich die einzelnen Knoten mit <xsl:template match="Name des Knotens"/> ansprechen muss.

Ist es möglich, dass ich ein Template aufrufe, dass eine bestimmte HTML-Formatierung mit sich bringt,
aber für jeden Knoten, für den ich es aufrufe im Grunde gleich ist, außer dass der Name des Knotens und dessen Inhalt ausgegeben wird?
Ich würde dann also sowas erzeugen wie:

```
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:template match="/">
          <html>
               <head>
                    <title>Thesis</title>
               </head>
               <body>
                    <xsl:for-each select="/">
                          <xsl:apply-templates />
                    </xsl:for-each>
    </body>
  </html>
  </xsl:template>

...

<xsl:template match="i-ter Knoten">
        <h1><xsl:value-of select="name()"/></h1>
        <p>
            <xsl:value-of select="."/>
        </p>
    </xsl:template>
</xsl:stylesheet>
```
Ich will also, dass die HTML-Formatierung, wie sie im unteren Template zu sehen ist, für jeden Unterknoten
vom Wurzelknoten des XML-Dokuments durchgeführt wird.
Leider weiß ich nicht, ob man dafür eine for-each-schleife verwenden kann und dann unten bei <xsl:template match="...."> den jeweiligen Knoten aus der Schleife ansprechen kann.

Im Gurnde will ich also verhindern, dass ich für jeden Unterknoten ein eigenes Template bauen muss,
also etwa:

```
<xsl:template match="1.Knoten">
        <h1><xsl:value-of select="name()"/></h1>
        <p>
            <xsl:value-of select="."/>
        </p>
    </xsl:template>

<xsl:template match="2.Knoten">
         <h1><xsl:value-of select="name()"/></h1>
         <p>
             <xsl:value-of select="."/>
         </p>
     </xsl:template>

usw.....
```
und oben dann diese Templates der Reihe nach mit 
	
	
	



```
<xsl:apply-templates select="1.Knoten"...
```
 etc. aufurfen muss.

Ist sowas möglich? Bietet sich dafür die for-each-Schleife an?


----------



## Sven Mintel (18. Januar 2010)

Meinst du so?:


```
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <head>
            <title>Thesis</title>
            </head>
            <body>
                <xsl:apply-templates />
            </body>
        </html>
    </xsl:template>


  <xsl:template match="*">
    <h1><xsl:value-of select='name()'/></h1>
    <p>
      <xsl:copy>   
        <xsl:copy-of select="@*"/>
          <xsl:apply-templates/>
      </xsl:copy>
    </p>
  </xsl:template>    

</xsl:stylesheet>
```

Den Pfad(besser gesagt den Knotennamen) kannst du ja als Wildcard * angeben.
Wichtig ist dieses Konstrukt aus copy und copy-of, das dafür sorgt, dass die Kindknoten des aktuellen Knotens kopiert werden und so im Weiteren Verlauf noch verarbeitet werden können(die Wildcard bezieht sich ja nur auf die aktuelle Ebene)


----------

