Wie kann ich überprüfen, ob ein Tag in XSLT vorhanden ist?

Ich habe die folgende Vorlage

<h2>one</h2>
<xsl:apply-templates select="one"/>
<h2>two</h2>
<xsl:apply-templates select="two"/>
<h2>three</h2>
<xsl:apply-templates select="three"/>

Ich möchte die Header (eins,zwei,drei) nur anzeigen, wenn mindestens ein Element der entsprechenden Vorlage vorhanden ist. Wie prüfe ich dies?

Antwort auf "Wie kann ich überprüfen, ob ein Tag in XSLT vorhanden ist? " 2 von antworten

<xsl:if test="one">
  <h2>one</h2>
  <xsl:apply-templates select="one"/>
</xsl:if>
<!-- etc -->

Alternativ könnte man eine benannte Vorlage erstellen,

<xsl:template name="WriteWithHeader">
   <xsl:param name="header"/>
   <xsl:param name="data"/>
   <xsl:if test="$data">
      <h2><xsl:value-of select="$header"/></h2>
      <xsl:apply-templates select="$data"/>
   </xsl:if>
</xsl:template>

und dann rufen:

  <xsl:call-template name="WriteWithHeader">
    <xsl:with-param name="header" select="'one'"/>
    <xsl:with-param name="data" select="one"/>
  </xsl:call-template>

Aber um ehrlich zu sein, das sieht für mich nach mehr Arbeit aus... nur nützlich, wenn das Zeichnen einer Kopfzeile komplex ist... für ein einfaches <h2>...</h2> I'd be tempted to leave it inline. wäre ich versucht, es inline zu lassen.

Wenn der Headertitel immer der Knotenname ist, können Sie die Vorlage vervielfältigen, indem Sie die "" arg entfernen und stattdessen verwenden:

<xsl:value-of select="name($header[1])"/>

Ich mache gerne die funktionalen Aspekte von XSL aus, die mich zu folgender Implementierung führen:

<?xml version="1.0" encoding="UTF-8"?>

<!-- test data inlined -->
<test>
    <one>Content 1</one>
    <two>Content 2</two>
    <three>Content 3</three>
    <four/>
    <special>I'm special!</special>
</test>

<!-- any root since take test content from stylesheet -->
<xsl:template match="/">
    <html>
        <head>
            <title>Header/Content Widget</title>
        </head>
        <body>
            <xsl:apply-templates select="document('')//test/*" mode="header-content-widget"/>
        </body>
    </html>
</xsl:template>

<!-- default action for header-content -widget is apply header then content views -->
<xsl:template match="*" mode="header-content-widget">
    <xsl:apply-templates select="." mode="header-view"/>
    <xsl:apply-templates select="." mode="content-view"/>
</xsl:template>

<!-- default header-view places element name in <h2> tag -->
<xsl:template match="*" mode="header-view">
    <h2><xsl:value-of select="name()"/></h2>
</xsl:template>

<!-- default header-view when no text content is no-op -->
<xsl:template match="*[not(text())]" mode="header-view"/>

<!-- default content-view is to apply-templates -->
<xsl:template match="*" mode="content-view">
    <xsl:apply-templates/>
</xsl:template>

<!-- special content handling -->
<xsl:template match="special" mode="content-view">
    <strong><xsl:apply-templates/></strong>
</xsl:template>

Einmal im Text sind alle Elemente im Test Element inhalt-header-widget angewendet (in Dokumentreihenfolge).

Die standardmäßige header-content-widget Vorlage (entspricht "*") wendet zuerst eine Headeransicht an und wendet dann eine Inhaltsansicht auf das aktuelle Element an.

Die standardmäßige Headeransicht vorlage platziert den Namen des aktuellen Elements im h2-Tag. Die Standard- Inhaltsansicht wendet generische Verarbeitungsregeln an.

Wenn es keinen Inhalt gibt, der vom Prädikat [not(text())] beurteilt wird, tritt keine Ausgabe für das Element auf.

Ein aus spezieller Gehäuse sind einfach zu handhaben.