brunft: Zwei-Phasen-Transformation

Hallo leute,

folgendes würde ich gerne mit XSLT realisieren:

Ausgangspunkt ist ein XML file, welches ich in ein HTML file transformieren möchte. Vor dieser HTML-Transformation möchte ich jedoch XML tags, die bestimmte Eigenschaften besitzen, in andere umwandeln.

Beispiel:
<artikelliste>
  <artikel name="GelberStuhl">
    <beschreibung>Beschreibung zu GelberStuhl</beschreibung>
    <preis>10</preis>
    <lieferant>Möbel Mustermann</lieferant>
  </artikel>
  <artikel name="AllgemeinerStuhl">
  <artikel name="BlauerTisch">
     <beschreibung>Beschreibung zu BlauerTisch</beschreibung>
     <preis>20</preis>
     <lieferant>Möbel Huber</lieferant
  <artikel>
</artikelliste>

Alle Artikel variieren in Beschreibung, Preis oder Lieferant, nur der Artikel "AllgemeinerStuhl" hat immer die gleichen Daten.
Da ich die Daten nicht jedes mal neu eingeben will, würde ich gerne die entspr. Artikel-XML tags mittels XLST erzeugen, bevor die Artikelliste nach HTML transformiert wird. (womit auch gewährleistet wäre, dass die HTML-Formatierung eines Artikels nur einmal existiert)

Mein erster Einfall war, zwei XSL files zu erstellen, jedoch fand ich auch in diesem Fall keinen vernünftigen Ansatz, das zu realisieren (Bin zum Schluss gekommen, dass ich im ersten XSL file, welches XML nach XML transformiert, wieder alle Elemente anführen muss, was die gewonnene Kapselung bei der HTML-Formatierung wieder aufhebt)
Ich habe nun stundenlang geforscht, bin aber zu keiner einfachen Lösung gekommen.

Bin für jeden Tip dankbar.

Grüße
brunft

  1. Hi!

    Beispiel:
    <artikelliste>
      <artikel name="GelberStuhl">
        <beschreibung>Beschreibung zu GelberStuhl</beschreibung>
        <preis>10</preis>
        <lieferant>Möbel Mustermann</lieferant>
      </artikel>
      <artikel name="AllgemeinerStuhl">

    Fehlt da nicht ein / am Ende?

    <artikel name="BlauerTisch">
         <beschreibung>Beschreibung zu BlauerTisch</beschreibung>
         <preis>20</preis>
         <lieferant>Möbel Huber</lieferant
      <artikel>

    Und hier am Anfang.

    </artikelliste>

    Mein erster Einfall war, zwei XSL files zu erstellen

    Hm, eigentlich kannst Du das nach Deiner Beschreibung doch auch mit einem lösen: wenn der Inhalt von "AllgemeinerStuhl" immer gleich ist, Du ihn also kennst, dann baust Du einfach ein Spezial-Template ein, welches diese Daten automatisch einfügt:

    <xsl:template match="Artikel">
    ...Beschreibung: <xsl:value-of select="beschreibung" />...
    </xsl:template>

    <xsl:template match="Artikel[@name='AllgemeinerStuhl']">
    ...Beschreibung: blabla...
    </xsl:template>

    VG->Cologne
    Simon

  2. hallo,

    folgendes würde ich gerne mit XSLT realisieren:

    Alle Artikel variieren in Beschreibung, Preis oder Lieferant, nur der Artikel "AllgemeinerStuhl" hat immer die gleichen Daten.

    so weit ist es zu verstehen.

    Da ich die Daten nicht jedes mal neu eingeben will,

    wo eingenben?

    würde ich gerne die entspr. Artikel-XML tags mittels XLST erzeugen,

    warum? bzw. wozu?

    dass ich im ersten XSL file, welches XML nach XML transformiert, wieder alle Elemente anführen muss, was die gewonnene Kapselung bei der HTML-Formatierung wieder aufhebt)

    wie bitte?

    ich glaube du bist zu sehr in das problem vertieft, denn es ist nciht wirklich zu verstehen was du möchtest.

    Bin für jeden Tip dankbar.

    wenn es darum geht, dass du
    <artikel name="AllgemeinerStuhl">
    öfters im ausgabe dokument brauchst und das immer anders dargestellt, dann kannst du mit sowas versuchen

    <xsl:template match="artikel[@name='AllgemeinerStuhl']" mode="eins">
    ...
    </xsl:template>

    <xsl:template match="artikel[@name='AllgemeinerStuhl']" mode="zwei">
    ...
    </xsl:template>

    und an den entsprechenden stellen so aufrufen:

    <xsl:apply-templates select="artikel[@name='AllgemeinerStuhl']" mode="eins"/>
    <xsl:apply-templates select="artikel[@name='AllgemeinerStuhl']" mode="zwei"/>

    grüße
    thomas

  3. Grüssi,

    Ausgangspunkt ist ein XML file, welches ich in ein HTML file transformieren möchte. Vor dieser HTML-Transformation möchte ich jedoch XML tags, die bestimmte Eigenschaften besitzen, in andere umwandeln.

    Alle Artikel variieren in Beschreibung, Preis oder Lieferant, nur der Artikel "AllgemeinerStuhl" hat immer die gleichen Daten.

    Die einfachste Möglichkeit wäre sicher die von Simon vorgeschlagene. Wenn du aber nicht die Stuhl-Daten fix ins stylesheet hard-codieren willst, sondern das xslt ev. für verschiedene xml-files verwenden willst, und nicht in jedem xml-file der AllgemeineStuhl die gleichen Daten hat, könntest du versuchen, die Daten einmal pro (xml)file zu definieren, und sie dann in der Artikelliste einfach zu referenzieren:

    <StandardArtikel>
      <artikel name="AllgemeinerStuhl">
        <beschreibung>Beschreibung zu AllgemeinerStuhl</beschreibung>
        <preis>10</preis>
        <lieferant>XYZ</lieferant>
      </artikel>
    </StandardArtikel>

    im Template musst du eine Artikel-Referenz dann irgendwie von einem normalen Artikel unterscheiden können, beispielsweise dadurch dass das Artikel-Element kein 'name' attribut besitzt sondern ein 'ref' attribut:

    <artikelliste>
      <artikel name="GelberStuhl">
        <beschreibung>Beschreibung zu GelberStuhl</beschreibung>
        <preis>10</preis>
        <lieferant>Möbel Mustermann</lieferant>
      </artikel>
      <artikel ref="AllgemeinerStuhl" />
      <artikel name="BlauerTisch">
         <beschreibung>Beschreibung zu BlauerTisch</beschreibung>
         <preis>20</preis>
         <lieferant>Möbel Huber</lieferant
      <artikel>
    </artikelliste>

    Nun könntest du hergehen und zwei verschiedene Templates erstellen. Das erste (falls das Artikel-Element ein 'name'-Attribut besitzt) ist trivial, und das machst du so wie du vorhast. Für zweiteres könnest du das jetzt ein wenig umbauen:

    <xsl:template match='artikel/@ref'>

    <!-- kleiner Workaround - unschön, denn es wird die for-schleife
            immer nur einmal aufgerufen, aber mir fällt gerade keine
            andere möglich kein ein, möglichst einfach einen ganzen
            knoten in einem template zu selektieren und ihn dort zu
            "verarbeiten" ;-) -->

    <xsl:for-each select="StandardArtikel/Artikel/@name={@ref}">
          Artikel: <xsl:value-of select="@name" /><br />
          Preis: <xsl:value-of select="preis" />
       </xs:for-each>

    xsl:template

    Einfach ein bissl rumprobieren ;-)

    lg regenfeld

    1. hallo B.

      <xsl:template match='artikel/@ref'>

      was 'wort wörtlich' genau »ref="AllgemeinerStuhl"« trifft, aber keine elemente.

      du meinst wohl <xsl:template match="artikel[@ref]²>

      <xsl:template match='artikel/@ref'>
         <xsl:for-each select="StandardArtikel/Artikel/@name={@ref}">

      was den folgenden pfad bedeutet:

      artikel/@ref/StandardArtikel/Artikel/

      den gibt es aber nicht, also trifft for-each zusätzlich auch nicht, auch dann nicht wenn artikel[@ref] genommen wird, denn der pfad geht dann noch immer so: artikel[@ref]/StandardArtikel/Artikel/  und den gibt es auch nicht.

      grüße
      thomas

      1. Hallo Thomas,

        Nun, *hüstel* ich war wiedermal zu schusselig ;-)

        <RootElement>
         <StandardArtikel>
          <artikel name="AllgemeinerStuhl">
           <beschreibung>Beschreibung zu AllgemeinerStuhl</beschreibung>
           <preis>10</preis>
           <lieferant>XYZ</lieferant>
          </artikel>
         </StandardArtikel>

        <artikelliste>
          <artikel name="GelberStuhl">
           <beschreibung>Beschreibung zu GelberStuhl</beschreibung>
           <preis>10</preis>
           <lieferant>Möbel Mustermann</lieferant>
          </artikel>
          <artikel ref="AllgemeinerStuhl" />
          <artikel name="BlauerTisch">
            <beschreibung>Beschreibung zu BlauerTisch</beschreibung>
            <preis>20</preis>
            <lieferant>Möbel Huber</lieferant
          <artikel>
         </artikelliste>
        </RootElement>

        <xsl:template match='artikel/@ref'>

        was 'wort wörtlich' genau »ref="AllgemeinerStuhl"« trifft, aber keine elemente.

        du meinst wohl <xsl:template match="artikel[@ref]²>

        Ja, meinte ich, flüchtigkeitsfehler ;-)

        <xsl:template match="artikel[@ref]">
          <xsl:for-each select="/RootElement/StandardArtikel/artikel[@name={@ref}]">
             Artikel: <xsl:value-of select="@name" /><br />
             Preis: <xsl:value-of select="preis" />
          </xs:for-each>
        xsl:template

        Sodala, das sollte so nun aber hinhauen! Immer diese Test-Patterns *grmpf*

        Aber gibts denn nun eine schönere Möglichkeit, *ohne* das For-Each Konstrukt. was ich mit meinem kleinen beispiel sagen wollte, hast du ja trotz der kleinen ... ähm ... umwege, ja sicherlich verstanden ;-)

        lg bernhard