droom: Anker in XML

Hallo all!
Ich habe folgende XML Struktur:

<page id="2">
  <text>Ein Link zu einem Field</text>
    <link>3</link>
  <field id="3">
    <text>Text von Field mit id 3</text>
  </field>
  <field id="4">
    <text>Ein Link zu einem Field</text>
    <link>3</link>
  </field>
</page>
<page id="5">
  <text>Ein Link zu einer Seite</text>
    <link>2</link>
</page>

Das heisst sowohl ein <page> als auch ein <field> kann einen <text> mit <link> enthalten. Wenn ich mit XSL nun das <text>-Element bearbeitet, weiss ich nicht, wie ich die Verlinkung machen kann. Irgendwie muss ich merken, ob ich zu einer <page> verlinke oder zu einem <field>. Wenn zu einem Field, dann muss dieselbe seite aufgerufen werden mit der id des Fields als Anker.
Ich habe so angefangen:

xsl:choose
    <xsl:when test="not(child::link)">
        <p><xsl:value-of select="." /></p>
    </xsl:when>
    <xsl:when test="xxxx">
        <p><a>
            <xsl:attribute name="href">index.php?id=xxxxx</xsl:attribute>
            <xsl:value-of select="const" />
        </a></p>
    </xsl:when>
    xsl:otherwise
        <p><a>
            <xsl:attribute name="href">index.php?id=xxxx</xsl:attribute>
            <xsl:value-of select="const" />
        </a></p>
    </xsl:otherwise>
   </xsl:choose>

Ich möchte einmal einen Link zu einer Seite konstruieren mit index.php?id=xx und einmal als Anker, wenn ich zu einem Field verlinke mit index.php?id=xx#xx

  1. Hallo,

    Wenn ich mit XSL nun das <text>-Element bearbeitet, weiss ich nicht, wie ich die Verlinkung machen kann. Irgendwie muss ich merken, ob ich zu einer <page> verlinke oder zu einem <field>. Wenn zu einem Field, dann muss dieselbe seite aufgerufen werden mit der id des Fields als Anker.

    Ich möchte einmal einen Link zu einer Seite konstruieren mit index.php?id=xx und einmal als Anker, wenn ich zu einem Field verlinke mit index.php?id=xx#xx

    ---------
     <xsl:template match="text">
      xsl:choose
       <xsl:when test="parent::page/link">
        <p>
         <a href="{concat('index.php?id=', parent::page/@id)}">
         <xsl:value-of select="const" />
         <!-- was auch immer "const" für ein Element ist, es sollte innerhalb vom text stehen sonst wird es nciht gefunden  -->
         </a>
        </p>
       </xsl:when>
       <xsl:when test="parent::field/link">
        <p>
         <a href="{concat('index.php?id=', ancestor::page[1]/@id, '#', parent::field/@id)}">
          <xsl:value-of select="const" />
          <!-- was auch immer "const" für ein Element ist, es sollte innerhalb vom text stehen sonst wird es nciht gefunden  -->
         </a>
        </p>
       </xsl:when>
       xsl:otherwise
        <p>
         <xsl:value-of select="."/>
        </p>
       </xsl:otherwise>
      </xsl:choose>
     </xsl:template>
    ------

    parent::page/link prüft ob <text> im <page> steht und ob <page> ein <link> enthält, parent::field/link geht analog.

    Falls <text> in einem <flied> steht, verweist "ancestor::page[1]" auf das erste <page> (vom <text> aus gesehen) was oberhalb vom <text> steht (falls innerhalb vom <page> kein anderes <page> vorkommen kann, kannst du das [1] auch weglassen)

    Grüße
    Thomas

    1. Hallo Thomas!

      schonmal vielen dank für deine Hilfe. Nur etwas habe ich vielleicht falsch beschrieben. Also ein <text> im <page> kann sowohl zu einer neuen seite zeigen als auch einen Anker sein. Analog für ein <text> in <field>.

      Darum habe ich mir gedacht, ich muss eigentlich gucken, ob das Element zwischen <link> und </link> auf eine Seite oder ein Field verweist und von da dann meine Links bauen.

      Also um einen Anker zu machen, musste ich sowas wie: <xsl:when test="field[@id = child::link]">. Nach dem Motto, habe ich ein Field gefunden, deren ID= das Link-element, mache ich einen Anker und analog für Seiten. Verstehst Du was ich meine?

      1. Hallo,

        Verstehst Du was ich meine?

        Ich bin nicht sicher, dass ich dich verstanden habe.

        schonmal vielen dank für deine Hilfe. Nur etwas habe ich vielleicht falsch beschrieben. Also ein <text> im <page> kann sowohl zu einer neuen seite zeigen als auch einen Anker sein. Analog für ein <text> in <field>.

        Also <link> enthält immer die ID auf die er weiwesen soll. Ich kann aus deinem XML nicht wirklich folgen ob diese ID wirklich in ID ist, d.h. eine Zahl als ID kann nur wirklich einmal vorkommen? (auch deshalb sind Zahlen schlecht als ID)

        Darum habe ich mir gedacht, ich muss eigentlich gucken, ob das Element zwischen <link> und </link> auf eine Seite oder ein Field verweist und von da dann meine Links bauen.

        Also um einen Anker zu machen, musste ich sowas wie: <xsl:when test="field[@id = child::link]">. Nach dem Motto, habe ich ein Field gefunden, deren ID= das Link-element, mache ich einen Anker und analog für Seiten.

        Wenn ich dich richtig verstanden habe, dann sollte das so gehen:
        (Problem wäre aber hiebei, wenn es mehrere <link>s im <page> oder im <field> gäbe)

        Grüße
        Thomas
        ----------
         <xsl:template match="text">
          <xsl:variable name="link">
           xsl:choose
            <xsl:when test="parent::page/link">
             <xsl:variable name="plink" select="parent::page/link" />
             xsl:choose
              <xsl:when test="//page[@id = $plink]">
               <xsl:value-of select="concat('?id=', //page[@id = $plink]/@id)"/>
              </xsl:when>
              <xsl:when test="//field[@id = $plink]">
               <xsl:value-of select="concat('?id=', //page/field[@id = $plink]/@id,  '#', $plink)"/>
              </xsl:when>
             </xsl:choose>
            </xsl:when>
            <xsl:when test="parent::field/link">
             <xsl:variable name="flink" select="parent::field/link" />
             xsl:choose
              <xsl:when test="//page[@id = $flink]">
               <xsl:value-of select="concat('?id=', //page[@id = $flink]/@id)"/>
              </xsl:when>
              <xsl:when test="//field[@id = $flink]">
               <xsl:value-of select="concat('?id=', //page/field[@id = $flink]/@id,  '#', $flink)"/>
              </xsl:when>
             </xsl:choose>
            </xsl:when>
           </xsl:choose>
          </xsl:variable>
          xsl:choose
           <xsl:when test="parent::page/link">
            <p>
             <a href="{concat('index.php', $link)}">
             <xsl:value-of select="const" />
             </a>
            </p>
           </xsl:when>
           <xsl:when test="parent::field/link">
            <p>
             <a href="{concat('index.php', $link)}">
              <xsl:value-of select="const" />
             </a>
            </p>
           </xsl:when>
           xsl:otherwise
            <p>
             <xsl:value-of select="."/>
            </p>
           </xsl:otherwise>
          </xsl:choose>
         </xsl:template>

        1. Hey Thomas!

          Ich weiss nicht, wie ich dir danken kann. Du bist mein Retter!

          God bless u! ;-)